Merge remote-tracking branch 'khronos-public/master' into 160811b-merge-master-to-android_layers

Update build-android/build.py and build-android/jni/Android.mk
to adjust for new shaderc build infrastructure.
Now pull shaderc from aosp to stay in sync with NDK builds.
diff --git a/BUILD.md b/BUILD.md
index ad05e86..70636db 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -35,7 +35,7 @@
 sudo apt-get install git cmake build-essential bison libx11-dev libxcb1-dev
 ```
 
-Example debug build (Note that the update\_external\_sources script used below builds external tools into predefined locations. See **LVL's Dependencies** for more information and other options):
+Example debug build (Note that the update\_external\_sources script used below builds external tools into predefined locations. See **Loader and Validation Layer Dependencies** for more information and other options):
 ```
 cd Vulkan-LoaderAndValidationLayers  # cd to the root of the cloned git repository
 ./update_external_sources.sh
@@ -52,9 +52,6 @@
 export LD_LIBRARY_PATH=<path to your repository root>/dbuild/loader
 export VK_LAYER_PATH=<path to your repository root>/dbuild/layers
 ```
-Note that if you have installed the [LunarG Vulkan SDK](https://vulkan.lunarg.com),
-you will also have the SDK version of the loader and layers installed in your default system libraries.
-
 You can run the `vulkaninfo` application to see which driver, loader and layers are being used.
 
 The `LoaderAndLayerInterface` document in the `loader` folder in this repository is a specification that
@@ -98,7 +95,7 @@
 - glslang is required for demos and tests.
   - [You can download and configure it (in a peer directory) here](https://github.com/KhronosGroup/glslang/blob/master/README.md)
   - A windows batch file has been included that will pull and build the correct version.  Run it from Developer Command Prompt for VS2013 like so:
-    - update\_external\_sources.bat --build-glslang (Note: see **LVL's Dependencies** below for other options)
+    - update\_external\_sources.bat --build-glslang (Note: see **Loader and Validation Layer Dependencies** below for other options)
 
 ## Windows Build - MSVC
 
@@ -106,7 +103,7 @@
 set the version numbers and build description for your build. Doing so will set the information displayed
 for the Properites->Details tab of the loader vulkan-1.dll file that is built.
 
-Build all Windows targets after installing required software and cloning the LVL repo as described above by completing the following steps in a "Developer Command Prompt for VS2013" window (Note that the update\_external\_sources script used below builds external tools into predefined locations. See **LVL's Dependencies** for more information and other options):
+Build all Windows targets after installing required software and cloning the Loader and Validation Layer repo as described above by completing the following steps in a "Developer Command Prompt for VS2013" window (Note that the update\_external\_sources script used below builds external tools into predefined locations. See **Loader and Validation Layer Dependencies** for more information and other options):
 ```
 cd Vulkan-LoaderAndValidationLayers  # cd to the root of the cloned git repository
 update_external_sources.bat --all
@@ -155,13 +152,11 @@
 ```
 - Ensure Homebrew is at the beginning of your PATH:
 ```
-export PATH=$HOME/homebrew/bin:$PATH
+export PATH=/usr/local/bin:$PATH
 ```
 - Add packages with the following (may need refinement)
 ```
-brew install cmake
-brew install python
-brew install python3
+brew install cmake python python3 git
 ```
 ### Build steps for Android
 Use the following to ensure the Android build works.
@@ -171,7 +166,7 @@
 cd build-android
 ./update_external_sources_android.sh
 ./android-generate.sh
-ndk-build
+ndk-build -j $(sysctl -n hw.ncpu)
 ```
 #### Windows
 Follow the setup steps for Windows above, then from Developer Command Prompt for VS2013:
@@ -185,13 +180,13 @@
 ## Ninja Builds - All Platforms
 The [Qt Creator IDE](https://qt.io/download-open-source/#section-2) can open a root CMakeList.txt as a project directly, and it provides tools within Creator to configure and generate Vulkan SDK build files for one to many targets concurrently, resolving configuration issues as needed. Alternatively, when invoking CMake use the -G Codeblocks Ninja option to generate Ninja build files to be used as project files for QtCreator
 
-- Follow the steps defined elsewhere for the OS using the update\_external\_sources script or as shown in **LVL's Dependencies** below
+- Follow the steps defined elsewhere for the OS using the update\_external\_sources script or as shown in **Loader and Validation Layer Dependencies** below
 - Open, configure, and build the gslang and spirv-tools CMakeList.txt files
 - Then do the same with the Vulkan-LoaderAndValidationLayers CMakeList.txt file.
 - In order to debug with QtCreator, a [Microsoft WDK: eg WDK 10](http://go.microsoft.com/fwlink/p/?LinkId=526733) is required. Note that installing the WDK breaks the MSVC vcvarsall.bat build scripts provided by MSVC, requiring that the LIB, INCLUDE, and PATH env variables be set to the WDK paths by some other means
 
-## LVL's Dependencies 
-gslang and SPIRV-Tools repos are required to build and run LVL components. They are not git sub-modules of Vulkan-LoaderAndValidationLayers but Vulkan-LoaderAndValidationLayers is linked to specific revisions of gslang and spirv-tools. These can be automatically cloned and built to predefined locations with the update\_external\_sources scripts. If a custom configuration is required, do the following steps:
+## Loader and Validation Layer Dependencies 
+gslang and SPIRV-Tools repos are required to build and run Loader and Validation Layer components. They are not git sub-modules of Vulkan-LoaderAndValidationLayers but Vulkan-LoaderAndValidationLayers is linked to specific revisions of gslang and spirv-tools. These can be automatically cloned and built to predefined locations with the update\_external\_sources scripts. If a custom configuration is required, do the following steps:
 
 1) clone the repos:
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
old mode 100755
new mode 100644
index e7e25b3..8df90e1
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -57,8 +57,6 @@
     include(FindPkgConfig)
 endif()
 
-set (CMAKE_INSTALL_PREFIX "")
-
 if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
     set(COMMON_COMPILE_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
     set(COMMON_COMPILE_FLAGS "${COMMON_COMPILE_FLAGS} -fno-strict-aliasing -fno-builtin-memcmp")
@@ -112,7 +110,7 @@
 
 #Choose natural default paths for glslang and SPIRV-Tools binaries to support custom definition by the user on the CMake command line or in the GUI
 set(GLSLANG_BINARY_ROOT "${CMAKE_BINARY_DIR}/../glslang" CACHE STRING "User defined path to the glslang binaries for this project")
-set(SPRIV_TOOLS_BINARY_ROOT "${CMAKE_BINARY_DIR}/../SPIRV-Tools" CACHE STRING "User defined path to the SPIRV-Tools binaries for this project")
+set(SPIRV_TOOLS_BINARY_ROOT "${CMAKE_BINARY_DIR}/../SPIRV-Tools" CACHE STRING "User defined path to the SPIRV-Tools binaries for this project")
 
 # Define a variable for a default root location to the gslang, SPIRV-Tools and other external sources and cache it to allow the user to customize it as needed
 set(EXTERNAL_SOURCE_ROOT "${CMAKE_SOURCE_DIR}/external" CACHE STRING "Root path to external sources such as glslang and SPIRV-Tools")
@@ -147,8 +145,8 @@
                                    "${GSLANG_FINAL_BINARY_PATH}/SPIRV/${DEBUG_DECORATION}")
 
     if(CUSTOM_SPIRV_TOOLS_BIN_ROOT)
-        set (SPIRV_TOOLS_SEARCH_PATH "${SPRIV_TOOLS_BINARY_ROOT}/${BUILDTGT_DIR}/source/${RELEASE_DECORATION}")
-        set (SPIRV_TOOLS_DEBUG_SEARCH_PATH "${SPRIV_TOOLS_BINARY_ROOT}/${BUILDTGT_DIR}/source/${DEBUG_DECORATION}")
+        set (SPIRV_TOOLS_SEARCH_PATH "${SPIRV_TOOLS_BINARY_ROOT}/${BUILDTGT_DIR}/source/${RELEASE_DECORATION}")
+        set (SPIRV_TOOLS_DEBUG_SEARCH_PATH "${SPIRV_TOOLS_BINARY_ROOT}/${BUILDTGT_DIR}/source/${DEBUG_DECORATION}")
     else()
         set (SPIRV_TOOLS_SEARCH_PATH "${EXTERNAL_SOURCE_ROOT}/spirv-tools/${BUILDTGT_DIR}/source/${RELEASE_DECORATION}")
         set (SPIRV_TOOLS_DEBUG_SEARCH_PATH "${EXTERNAL_SOURCE_ROOT}/spirv-tools/${BUILDTGT_DIR}/source/${DEBUG_DECORATION}")
@@ -168,7 +166,7 @@
     endif()
 
     if(CUSTOM_SPIRV_TOOLS_BIN_ROOT)
-        set (SPIRV_TOOLS_SEARCH_PATH "${SPRIV_TOOLS_BINARY_ROOT}/source" )
+        set (SPIRV_TOOLS_SEARCH_PATH "${SPIRV_TOOLS_BINARY_ROOT}/source" )
     else()
         set (SPIRV_TOOLS_SEARCH_PATH "${EXTERNAL_SOURCE_ROOT}/spirv-tools/${BUILDTGT_DIR}/source" "${CMAKE_SOURCE_DIR}/../x86_64/lib/spirv-tools" )
     endif()
@@ -217,15 +215,15 @@
     add_library(Loader      STATIC IMPORTED)
     add_library(SPIRV-Tools STATIC IMPORTED)
 
-    find_library(GLSLANG_DLIB NAMES glslang
+    find_library(GLSLANG_DLIB NAMES glslangd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
-    find_library(OGLCompiler_DLIB NAMES OGLCompiler
+    find_library(OGLCompiler_DLIB NAMES OGLCompilerd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
-    find_library(OSDependent_DLIB NAMES OSDependent
+    find_library(OSDependent_DLIB NAMES OSDependentd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
-    find_library(HLSL_DLIB NAMES HLSL
+    find_library(HLSL_DLIB NAMES HLSLd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
-    find_library(SPIRV_DLIB NAMES SPIRV
+    find_library(SPIRV_DLIB NAMES SPIRVd
                  HINTS ${GLSLANG_DEBUG_SEARCH_PATH} )
     find_library(SPIRV_TOOLS_DLIB NAMES SPIRV-Tools
                  HINTS ${SPIRV_TOOLS_DEBUG_SEARCH_PATH} )
@@ -262,7 +260,7 @@
     include(GNUInstallDirs)
     add_definitions(-DSYSCONFDIR="${CMAKE_INSTALL_SYSCONFDIR}")
     add_definitions(-DDATADIR="${CMAKE_INSTALL_DATADIR}")
-    if (CMAKE_INSTALL_PREFIX STREQUAL "/usr")
+    if (CMAKE_INSTALL_PREFIX STREQUAL "/usr/local")
     elseif (CMAKE_INSTALL_PREFIX STREQUAL "")
     else()
         add_definitions(-DLOCALPREFIX="${CMAKE_INSTALL_PREFIX}")
diff --git a/README.md b/README.md
old mode 100755
new mode 100644
index 4b7fde4..c23e716
--- a/README.md
+++ b/README.md
@@ -1,49 +1,50 @@
-# Vulkan Ecosystem Components

-

-This project provides Khronos official ICD loader and validation layers for Vulkan developers on Windows and Linux.

-

-## Introduction

-

-Vulkan is an Explicit API, enabling direct control over how GPUs actually work. No (or very little) validation

-or error checking is done inside a Vulkan driver. Applications have full control and responsibility. Any errors in

-how Vulkan is used often result in a crash. This project provides standard validation layers that can be enabled to ease development by 

-helping developers verify their applications correctly use the Vulkan API.

-

-Vulkan supports multiple GPUs and multiple global contexts (VkInstance). The ICD loader is necessary to support multiple GPUs  and the VkInstance level Vulkan commands.  Additionally, the loader manages inserting Vulkan layer libraries,

-including validation layers between the application and the ICD.

-

-The following components are available in this repository:

-- Vulkan header files

-- [*ICD Loader*](loader/)

-- [*Validation Layers*](layers/)

-- Demos and tests for the loader and validation layers

-

-## Contributing

-

-If you intend to contribute, the preferred work flow is for you to develop your contribution

-in a fork of this repo in your GitHub account and then submit a pull request.

-Please see the [CONTRIBUTING](CONTRIBUTING.md) file in this respository for more details

-

-## How to Build and Run

-

-[BUILD.md](BUILD.md)

-includes directions for building all the components, running the validation tests and running the demo applications.

-

-Information on how to enable the various Validation layers is in

-[layers/README.md](layers/README.md).

-

-Architecture and interface information for the loader is in

-[loader/LoaderAndLayerInterface.md](loader/LoaderAndLayerInterface.md).

-

-## License

-This work is released as open source under a Apache-style license from Khronos including a Khronos copyright.

-

-See COPYRIGHT.txt for a full list of licenses used in this repository.

-

-## Acknowledgements

-While this project has been developed primarily by LunarG, Inc; there are many other

-companies and individuals making this possible: Valve Corporation, funding

-project development; Google providing significant contributions to the validation layers;

-Khronos providing oversight and hosting of the project.

-

-

+# Vulkan Ecosystem Components
+
+This project provides Khronos official ICD loader and validation layers for Vulkan developers on Windows and Linux.
+
+## Introduction
+
+Vulkan is an Explicit API, enabling direct control over how GPUs actually work. No (or very little) validation
+or error checking is done inside a Vulkan driver. Applications have full control and responsibility. Any errors in
+how Vulkan is used often result in a crash. This project provides standard validation layers that can be enabled
+to ease development by helping developers verify their applications correctly use the Vulkan API.
+
+Vulkan supports multiple GPUs and multiple global contexts (VkInstance). The ICD loader is necessary to
+support multiple GPUs  and the VkInstance level Vulkan commands.  Additionally, the loader manages inserting
+Vulkan layer libraries, including validation layers between the application and the ICD.
+
+The following components are available in this repository:
+- Vulkan header files
+- [*ICD Loader*](loader/)
+- [*Validation Layers*](layers/)
+- Demos and tests for the loader and validation layers
+
+## Contributing
+
+If you intend to contribute, the preferred work flow is for you to develop your contribution
+in a fork of this repo in your GitHub account and then submit a pull request.
+Please see the [CONTRIBUTING](CONTRIBUTING.md) file in this respository for more details
+
+## How to Build and Run
+
+[BUILD.md](BUILD.md)
+includes directions for building all the components, running the validation tests and running the demo applications.
+
+Information on how to enable the various Validation layers is in
+[layers/README.md](layers/README.md).
+
+Architecture and interface information for the loader is in
+[loader/LoaderAndLayerInterface.md](loader/LoaderAndLayerInterface.md).
+
+## License
+This work is released as open source under a Apache-style license from Khronos including a Khronos copyright.
+
+See COPYRIGHT.txt for a full list of licenses used in this repository.
+
+## Acknowledgements
+While this project has been developed primarily by LunarG, Inc; there are many other
+companies and individuals making this possible: Valve Corporation, funding
+project development; Google providing significant contributions to the validation layers;
+Khronos providing oversight and hosting of the project.
+
+
diff --git a/build-android/AndroidManifest.xml b/build-android/AndroidManifest.xml
new file mode 100644
index 0000000..45a26b6
--- /dev/null
+++ b/build-android/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>

+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.VulkanLayerValidationTests" android:versionCode="1" android:versionName="1.0">

+

+    <!-- This is the platform API where NativeActivity was introduced. -->

+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/>

+

+    <!-- This .apk has no Java code itself, so set hasCode to false. -->

+    <application android:label="@string/app_name" android:hasCode="false" android:debuggable='false'>

+

+        <!-- This allows writing log files to sdcard -->

+        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

+

+        <!-- Our activity is the built-in NativeActivity framework class.

+             This will take care of integrating with our NDK code. -->

+        <activity android:name="android.app.NativeActivity" android:label="@string/app_name" android:exported="true">

+            <!-- Tell NativeActivity the name of or .so -->

+            <meta-data android:name="android.app.lib_name" android:value="VulkanLayerValidationTests"/>

+            <intent-filter>

+                <action android:name="android.intent.action.MAIN"/>

+                <category android:name="android.intent.category.LAUNCHER"/>

+            </intent-filter>

+        </activity>

+    </application>

+

+</manifest>

diff --git a/build-android/android-generate.bat b/build-android/android-generate.bat
index df3dd33..a70642e 100644
--- a/build-android/android-generate.bat
+++ b/build-android/android-generate.bat
@@ -24,7 +24,6 @@
 python ../vk_helper.py --gen_enum_string_helper ../include/vulkan/vulkan.h --abs_out_dir generated/include

 python ../vk_helper.py --gen_struct_wrappers ../include/vulkan/vulkan.h --abs_out_dir generated/include

 

-python ../vk-layer-generate.py Android object_tracker ../include/vulkan/vulkan.h > generated/include/object_tracker.cpp

 python ../vk-layer-generate.py Android unique_objects ../include/vulkan/vulkan.h > generated/include/unique_objects.cpp

 

 cd generated/include

@@ -41,24 +40,21 @@
 REM create build-script root directory

 mkdir generated\gradle-build

 cd generated\gradle-build

-mkdir  core_validation device_limits image object_tracker parameter_validation swapchain threading unique_objects

+mkdir  core_validation image object_tracker parameter_validation swapchain threading unique_objects

 cd ..\..

 mkdir generated\layer-src

 cd generated\layer-src

-mkdir  core_validation device_limits image object_tracker parameter_validation swapchain threading unique_objects

+mkdir  core_validation image object_tracker parameter_validation swapchain threading unique_objects

 cd ..\..

 xcopy /s gradle-templates\*   generated\gradle-build\

-for %%G in (core_validation device_limits image parameter_validation swapchain threading) Do (

+for %%G in (core_validation image object_tracker parameter_validation swapchain threading) Do (

     copy ..\layers\%%G.cpp   generated\layer-src\%%G

     echo apply from: "../common.gradle"  > generated\gradle-build\%%G\build.gradle

 )

-copy generated\include\object_tracker.cpp   generated\layer-src\object_tracker

-echo apply from: "../common.gradle"  > generated\gradle-build\object_tracker\build.gradle

-copy generated\include\unique_objects.cpp   generated\layer-src\unique_objects

+copy generated\include\unique_objects.cpp generated\layer-src\unique_objects

 copy generated\common\descriptor_sets.cpp generated\layer-src\core_validation\descriptor_sets.cpp

 copy generated\include\vk_safe_struct.cpp generated\layer-src\core_validation\vk_safe_struct.cpp

 move generated\include\vk_safe_struct.cpp generated\layer-src\unique_objects\vk_safe_struct.cpp

 echo apply from: "../common.gradle"  > generated\gradle-build\unique_objects\build.gradle

 

-del  /f /q generated\include\object_tracker.cpp

 del  /f /q generated\include\unique_objects.cpp

diff --git a/build-android/android-generate.sh b/build-android/android-generate.sh
index 6e9bd09..fb0e867 100755
--- a/build-android/android-generate.sh
+++ b/build-android/android-generate.sh
@@ -26,7 +26,6 @@
 python ../vk_helper.py --gen_enum_string_helper ../include/vulkan/vulkan.h --abs_out_dir generated/include
 python ../vk_helper.py --gen_struct_wrappers ../include/vulkan/vulkan.h --abs_out_dir generated/include
 
-python ../vk-layer-generate.py Android object_tracker ../include/vulkan/vulkan.h > generated/include/object_tracker.cpp
 python ../vk-layer-generate.py Android unique_objects ../include/vulkan/vulkan.h > generated/include/unique_objects.cpp
 ( cd generated/include; python ../../../genvk.py threading -registry ../../../vk.xml thread_check.h )
 ( cd generated/include; python ../../../genvk.py paramchecker -registry ../../../vk.xml parameter_validation.h )
@@ -40,8 +39,8 @@
 # layer names and their original source files directory
 # 1 to 1 correspondence -- one layer one source file; additional files are copied
 # at fixup step
-declare layers=(core_validation device_limits image object_tracker parameter_validation swapchain threading unique_objects)
-declare src_dirs=(../layers ../layers ../layers generated/include ../layers ../layers ../layers generated/include)
+declare layers=(core_validation image object_tracker parameter_validation swapchain threading unique_objects)
+declare src_dirs=(../layers ../layers ../layers ../layers ../layers ../layers generated/include)
 
 SRC_ROOT=generated/layer-src
 BUILD_ROOT=generated/gradle-build
@@ -65,7 +64,6 @@
 mv  generated/include/vk_safe_struct.cpp ${SRC_ROOT}/unique_objects/vk_safe_struct.cpp
 
 # fixup - remove copied files from generated/include
-rm  generated/include/object_tracker.cpp
 rm  generated/include/unique_objects.cpp
 
 exit 0
diff --git a/build-android/build.py b/build-android/build.py
index bf06622..ed55b62 100755
--- a/build-android/build.py
+++ b/build-android/build.py
@@ -20,9 +20,45 @@
 import os
 import subprocess
 import sys
+import shutil
 
 from subprocess import PIPE, STDOUT
 
+def install_file(file_name, src_dir, dst_dir):
+    src_file = os.path.join(src_dir, file_name)
+    dst_file = os.path.join(dst_dir, file_name)
+
+    print('Copying {} to {}...'.format(src_file, dst_file))
+    if os.path.isdir(src_file):
+        _install_dir(src_file, dst_file)
+    elif os.path.islink(src_file):
+        _install_symlink(src_file, dst_file)
+    else:
+        _install_file(src_file, dst_file)
+
+
+def _install_dir(src_dir, dst_dir):
+    parent_dir = os.path.normpath(os.path.join(dst_dir, '..'))
+    if not os.path.exists(parent_dir):
+        os.makedirs(parent_dir)
+    shutil.copytree(src_dir, dst_dir, symlinks=True)
+
+
+def _install_symlink(src_file, dst_file):
+    dirname = os.path.dirname(dst_file)
+    if not os.path.exists(dirname):
+        os.makedirs(dirname)
+    link_target = os.readlink(src_file)
+    os.symlink(link_target, dst_file)
+
+
+def _install_file(src_file, dst_file):
+    dirname = os.path.dirname(dst_file)
+    if not os.path.exists(dirname):
+        os.makedirs(dirname)
+    # copy2 is just copy followed by copystat (preserves file metadata).
+    shutil.copy2(src_file, dst_file)
+
 THIS_DIR = os.path.realpath(os.path.dirname(__file__))
 
 ALL_ARCHITECTURES = (
@@ -82,8 +118,6 @@
 
 
 def main():
-  print('Constructing Vulkan validation layer source...')
-
   print('THIS_DIR: %s' % THIS_DIR)
   parser = ArgParser()
   args = parser.parse_args()
@@ -103,8 +137,8 @@
   for arch in arches:
     abis.extend(arch_to_abis(arch))
 
-  shaderc_dir = THIS_DIR + '/../../shaderc/shaderc/android_test'
-  print('shaderc_dir = %s' % shaderc_dir)
+  shaderc_path = installdir + '/shaderc/android_test'
+  print('shaderc_path = %s' % shaderc_path)
 
   if os.path.isdir('/buildbot/android-ndk'):
     ndk_dir = '/buildbot/android-ndk'
@@ -132,9 +166,92 @@
   print('obj_out: %s' % obj_out)
   print('lib_out: %s' % lib_out)
 
+  print('Constructing shaderc build tree...')
+  shaderc_root_dir = os.path.join(THIS_DIR, '../../shaderc')
+
+  copies = [
+      {
+          'source_dir': os.path.join(shaderc_root_dir, 'shaderc'),
+          'dest_dir': 'shaderc',
+          'files': [
+              'Android.mk', 'libshaderc/Android.mk',
+              'libshaderc_util/Android.mk',
+              'third_party/Android.mk',
+              'utils/update_build_version.py',
+              'CHANGES',
+          ],
+          'dirs': [
+              'libshaderc/include', 'libshaderc/src',
+              'libshaderc_util/include', 'libshaderc_util/src',
+              'android_test'
+          ],
+      },
+      {
+          'source_dir': os.path.join(shaderc_root_dir, 'spirv-tools'),
+          'dest_dir': 'shaderc/third_party/spirv-tools',
+          'files': [
+              'utils/generate_grammar_tables.py',
+              'utils/update_build_version.py',
+              'CHANGES',
+          ],
+          'dirs': ['include', 'source'],
+      },
+      {
+          'source_dir': os.path.join(shaderc_root_dir, 'spirv-headers'),
+          'dest_dir':
+              'shaderc/third_party/spirv-tools/external/spirv-headers',
+          'dirs': ['include',],
+          'files': [
+              'include/spirv/1.0/spirv.py',
+              'include/spirv/1.1/spirv.py'
+          ],
+      },
+      {
+          'source_dir': os.path.join(shaderc_root_dir, 'glslang'),
+          'dest_dir': 'shaderc/third_party/glslang',
+          'files': ['glslang/OSDependent/osinclude.h'],
+          'dirs': [
+              'SPIRV',
+              'OGLCompilersDLL',
+              'glslang/GenericCodeGen',
+              'hlsl',
+              'glslang/Include',
+              'glslang/MachineIndependent',
+              'glslang/OSDependent/Unix',
+              'glslang/Public',
+          ],
+      },
+  ]
+
+  default_ignore_patterns = shutil.ignore_patterns(
+      "*CMakeLists.txt",
+      "*.py",
+      "*test.h",
+      "*test.cc")
+
+  for properties in copies:
+      source_dir = properties['source_dir']
+      dest_dir = os.path.join(installdir, properties['dest_dir'])
+      for d in properties['dirs']:
+          src = os.path.join(source_dir, d)
+          dst = os.path.join(dest_dir, d)
+          print(src, " -> ", dst)
+          shutil.copytree(src, dst,
+                          ignore=default_ignore_patterns)
+      for f in properties['files']:
+          print(source_dir, ':', dest_dir, ":", f)
+          # Only copy if the source file exists.  That way
+          # we can update this script in anticipation of
+          # source files yet-to-come.
+          if os.path.exists(os.path.join(source_dir, f)):
+              install_file(f, source_dir, dest_dir)
+          else:
+              print(source_dir, ':', dest_dir, ":", f, "SKIPPED")
+
   print('Building shader toolchain...')
   build_cmd = [
-    'bash', ndk_build, '-C', shaderc_dir, jobs_arg(),
+    'bash', ndk_build, '-C', shaderc_path,
+    jobs_arg(),
     'APP_ABI=' + ' '.join(abis),
     # Use the prebuilt platforms and toolchains.
     'NDK_PLATFORMS_ROOT=' + platforms_root,
@@ -146,20 +263,23 @@
     # typical ndk-build layout with a jni/{Android,Application}.mk.
     'NDK_PROJECT_PATH=null',
     'NDK_TOOLCHAIN_VERSION=' + compiler,
-    'APP_BUILD_SCRIPT=' + os.path.join(shaderc_dir, 'jni', 'Android.mk'),
+    'APP_BUILD_SCRIPT=' + os.path.join(shaderc_path, 'jni', 'Android.mk'),
     'APP_STL=' + stl,
-    'NDK_APPLICATION_MK=' + os.path.join(shaderc_dir, 'jni', 'Application.mk'),
-    'NDK_OUT=' + os.path.join(shaderc_dir, 'obj'),
-    'NDK_LIBS_OUT=' + os.path.join(shaderc_dir, 'jniLibs'),
-    'THIRD_PARTY_PATH=../..',
+    'NDK_APPLICATION_MK=' + os.path.join(shaderc_path, 'jni', 'Application.mk'),
+    'NDK_OUT=' + os.path.join(shaderc_path, 'obj'),
+    'NDK_LIBS_OUT=' + os.path.join(shaderc_path, 'jniLibs'),
+    'THIRD_PARTY_PATH=../third_party',
 
     # Put armeabi-v7a-hard in its own directory.
     '_NDK_TESTING_ALL_=yes'
   ]
+  print(' '.join(build_cmd))
 
   subprocess.check_call(build_cmd)
   print('Finished shader toolchain build')
 
+  print('Constructing Vulkan validation layer source...')
+
   build_cmd = [
     'bash', THIS_DIR + '/android-generate.sh'
   ]
@@ -169,7 +289,8 @@
 
 
   build_cmd = [
-    'bash', ndk_build, '-C', build_dir, jobs_arg(),
+    'bash', ndk_build, '-C', build_dir,
+    jobs_arg(),
     'APP_ABI=' + ' '.join(abis),
     # Use the prebuilt platforms and toolchains.
     'NDK_PLATFORMS_ROOT=' + platforms_root,
@@ -187,6 +308,8 @@
     'NDK_OUT=' + obj_out,
     'NDK_LIBS_OUT=' + lib_out,
     'THIRD_PARTY_PATH=',
+    'SHADERC_OBJ_PATH=' + shaderc_path + '/obj',
+    'EXTERNAL_INCLUDE_PATH=' + installdir + '/shaderc',
 
     # Put armeabi-v7a-hard in its own directory.
     '_NDK_TESTING_ALL_=yes'
@@ -194,6 +317,8 @@
 
   print('Building Vulkan validation layers for ABIs:' +
     ' {}'.format(', '.join(abis)))
+  print(' '.join(build_cmd))
+
   subprocess.check_call(build_cmd)
 
   print('Finished building Vulkan validation layers')
diff --git a/build-android/glslang_revision_android b/build-android/glslang_revision_android
index 56c5bed..1f7391f 100644
--- a/build-android/glslang_revision_android
+++ b/build-android/glslang_revision_android
@@ -1 +1 @@
-d99524197f3b68dbd6267bd3f4d7e8a0f49167b4
+master
diff --git a/build-android/gradle-templates/settings.gradle b/build-android/gradle-templates/settings.gradle
index 00a0cba..d4c9c99 100644
--- a/build-android/gradle-templates/settings.gradle
+++ b/build-android/gradle-templates/settings.gradle
@@ -1,5 +1,4 @@
 include ':core_validation',
-        ':device_limits',
         ':image',
         ':object_tracker',
         ':parameter_validation',
diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk
index 07d48d5..7c51a6b 100644
--- a/build-android/jni/Android.mk
+++ b/build-android/jni/Android.mk
@@ -34,6 +34,11 @@
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
+ifdef EXTERNAL_INCLUDE_PATH
+    EXTERNAL_INCLUDE := $(EXTERNAL_INCLUDE_PATH)/third_party
+else
+    EXTERNAL_INCLUDE := $(SRC_DIR)/external
+endif
 LOCAL_MODULE := VkLayer_core_validation
 LOCAL_SRC_FILES += $(LAYER_DIR)/layer-src/core_validation/core_validation.cpp
 LOCAL_SRC_FILES += $(LAYER_DIR)/layer-src/core_validation/descriptor_sets.cpp
@@ -43,27 +48,14 @@
                     $(SRC_DIR)/layers \
                     $(LAYER_DIR)/include \
                     $(SRC_DIR)/loader \
-                    $(GLSLANG_DIR) \
-                    $(SPIRV_TOOLS_DIR)/include
+                    $(EXTERNAL_INCLUDE)/glslang \
+                    $(EXTERNAL_INCLUDE)/spirv-tools/include
 LOCAL_STATIC_LIBRARIES += layer_utils SPIRV-Tools-prebuilt
 LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR
 LOCAL_LDLIBS    := -llog
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := VkLayer_device_limits
-LOCAL_SRC_FILES += $(LAYER_DIR)/layer-src/device_limits/device_limits.cpp
-LOCAL_SRC_FILES += $(LAYER_DIR)/common/vk_layer_table.cpp
-LOCAL_C_INCLUDES += $(SRC_DIR)/include \
-                    $(SRC_DIR)/layers \
-                    $(LAYER_DIR)/include \
-                    $(SRC_DIR)/loader
-LOCAL_STATIC_LIBRARIES += layer_utils
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR
-LOCAL_LDLIBS    := -llog
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
 LOCAL_MODULE := VkLayer_image
 LOCAL_SRC_FILES += $(LAYER_DIR)/layer-src/image/image.cpp
 LOCAL_SRC_FILES += $(LAYER_DIR)/common/vk_layer_table.cpp
@@ -142,9 +134,138 @@
 LOCAL_LDLIBS    := -llog
 include $(BUILD_SHARED_LIBRARY)
 
+# Pull in prebuilt shaderc
 include $(CLEAR_VARS)
-LOCAL_MODULE := SPIRV-Tools-prebuilt
-LOCAL_SRC_FILES := $(SHADERC_DIR)/shaderc/android_test/obj/local/$(TARGET_ARCH_ABI)/libSPIRV-Tools.a
+ifdef SHADERC_OBJ_PATH
+    SHADERC_OBJ_PATH := $(SHADERC_OBJ_PATH)
+else
+    SHADERC_OBJ_PATH := $(SRC_DIR)/external/shaderc/android_test/obj
+endif
+LOCAL_MODULE := shaderc-prebuilt
+LOCAL_SRC_FILES := $(SHADERC_OBJ_PATH)/local/$(TARGET_ARCH_ABI)/libshaderc.a
 include $(PREBUILT_STATIC_LIBRARY)
 
+include $(CLEAR_VARS)
+ifdef SHADERC_OBJ_PATH
+    SHADERC_OBJ_PATH := $(SHADERC_OBJ_PATH)
+else
+    SHADERC_OBJ_PATH := $(SRC_DIR)/external/shaderc/android_test/obj
+endif
+LOCAL_MODULE := glslang-prebuilt
+LOCAL_SRC_FILES := $(SHADERC_OBJ_PATH)/local/$(TARGET_ARCH_ABI)/libglslang.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+ifdef SHADERC_OBJ_PATH
+    SHADERC_OBJ_PATH := $(SHADERC_OBJ_PATH)
+else
+    SHADERC_OBJ_PATH := $(SRC_DIR)/external/shaderc/android_test/obj
+endif
+LOCAL_MODULE := OGLCompiler-prebuilt
+LOCAL_SRC_FILES := $(SHADERC_OBJ_PATH)/local/$(TARGET_ARCH_ABI)/libOGLCompiler.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+ifdef SHADERC_OBJ_PATH
+    SHADERC_OBJ_PATH := $(SHADERC_OBJ_PATH)
+else
+    SHADERC_OBJ_PATH := $(SRC_DIR)/external/shaderc/android_test/obj
+endif
+LOCAL_MODULE := OSDependent-prebuilt
+LOCAL_SRC_FILES := $(SHADERC_OBJ_PATH)/local/$(TARGET_ARCH_ABI)/libOSDependent.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+ifdef SHADERC_OBJ_PATH
+    SHADERC_OBJ_PATH := $(SHADERC_OBJ_PATH)
+else
+    SHADERC_OBJ_PATH := $(SRC_DIR)/external/shaderc/android_test/obj
+endif
+LOCAL_MODULE := HLSL-prebuilt
+LOCAL_SRC_FILES := $(SHADERC_OBJ_PATH)/local/$(TARGET_ARCH_ABI)/libHLSL.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+ifdef SHADERC_OBJ_PATH
+    SHADERC_OBJ_PATH := $(SHADERC_OBJ_PATH)
+else
+    SHADERC_OBJ_PATH := $(SRC_DIR)/external/shaderc/android_test/obj
+endif
+LOCAL_MODULE := shaderc_util-prebuilt
+LOCAL_SRC_FILES := $(SHADERC_OBJ_PATH)/local/$(TARGET_ARCH_ABI)/libshaderc_util.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+ifdef SHADERC_OBJ_PATH
+    SHADERC_OBJ_PATH := $(SHADERC_OBJ_PATH)
+else
+    SHADERC_OBJ_PATH := $(SRC_DIR)/external/shaderc/android_test/obj
+endif
+LOCAL_MODULE := SPIRV-prebuilt
+LOCAL_SRC_FILES := $(SHADERC_OBJ_PATH)/local/$(TARGET_ARCH_ABI)/libSPIRV.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+ifdef SHADERC_OBJ_PATH
+    SHADERC_OBJ_PATH := $(SHADERC_OBJ_PATH)
+else
+    SHADERC_OBJ_PATH := $(SRC_DIR)/external/shaderc/android_test/obj
+endif
+LOCAL_MODULE := SPIRV-Tools-prebuilt
+LOCAL_SRC_FILES := $(SHADERC_OBJ_PATH)/local/$(TARGET_ARCH_ABI)/libSPIRV-Tools.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+ifdef EXTERNAL_INCLUDE_PATH
+    EXTERNAL_INCLUDE := $(EXTERNAL_INCLUDE_PATH)
+else
+    EXTERNAL_INCLUDE := $(SRC_DIR)/external/shaderc
+endif
+LOCAL_MODULE := VkLayerValidationTests
+LOCAL_SRC_FILES += $(SRC_DIR)/tests/layer_validation_tests.cpp \
+                   $(SRC_DIR)/tests/vktestbinding.cpp \
+                   $(SRC_DIR)/tests/vktestframeworkandroid.cpp \
+                   $(SRC_DIR)/tests/vkrenderframework.cpp \
+                   $(SRC_DIR)/common/vulkan_wrapper.cpp
+LOCAL_C_INCLUDES += $(SRC_DIR)/include \
+                    $(SRC_DIR)/layers \
+                    $(SRC_DIR)/libs \
+                    $(SRC_DIR)/common \
+                    $(SRC_DIR)/icd/common \
+                    $(EXTERNAL_INCLUDE)/libshaderc/include
+
+LOCAL_STATIC_LIBRARIES := googletest_main layer_utils
+LOCAL_SHARED_LIBRARIES += shaderc-prebuilt glslang-prebuilt OGLCompiler-prebuilt OSDependent-prebuilt HLSL-prebuilt shaderc_util-prebuilt SPIRV-prebuilt SPIRV-Tools-prebuilt
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR --include=$(SRC_DIR)/common/vulkan_wrapper.h
+LOCAL_LDLIBS := -llog
+include $(BUILD_EXECUTABLE)
+
+# Note: The following module is similar in name to the executable, but differs so that loader won't enumerate the resulting .so
+include $(CLEAR_VARS)
+ifdef EXTERNAL_INCLUDE_PATH
+    EXTERNAL_INCLUDE := $(EXTERNAL_INCLUDE_PATH)
+else
+    EXTERNAL_INCLUDE := $(SRC_DIR)/external/shaderc
+endif
+LOCAL_MODULE := VulkanLayerValidationTests
+LOCAL_SRC_FILES += $(SRC_DIR)/tests/layer_validation_tests.cpp \
+                   $(SRC_DIR)/tests/vktestbinding.cpp \
+                   $(SRC_DIR)/tests/vktestframeworkandroid.cpp \
+                   $(SRC_DIR)/tests/vkrenderframework.cpp \
+                   $(SRC_DIR)/common/vulkan_wrapper.cpp
+LOCAL_C_INCLUDES += $(SRC_DIR)/include \
+                    $(SRC_DIR)/layers \
+                    $(SRC_DIR)/libs \
+                    $(SRC_DIR)/common \
+                    $(SRC_DIR)/icd/common \
+                    $(EXTERNAL_INCLUDE)/libshaderc/include
+
+LOCAL_STATIC_LIBRARIES := googletest_main layer_utils
+LOCAL_SHARED_LIBRARIES += shaderc-prebuilt glslang-prebuilt OGLCompiler-prebuilt OSDependent-prebuilt HLSL-prebuilt shaderc_util-prebuilt SPIRV-prebuilt SPIRV-Tools-prebuilt
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVALIDATION_APK --include=$(SRC_DIR)/common/vulkan_wrapper.h
+LOCAL_WHOLE_STATIC_LIBRARIES += android_native_app_glue
+LOCAL_LDLIBS := -llog -landroid
+include $(BUILD_SHARED_LIBRARY)
+
+$(call import-module,android/native_app_glue)
 $(call import-module,third_party/googletest)
diff --git a/build-android/jni/Application.mk b/build-android/jni/Application.mk
index 13ec240..8b4fb09 100644
--- a/build-android/jni/Application.mk
+++ b/build-android/jni/Application.mk
@@ -16,6 +16,6 @@
 APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 mips mips64

 APP_PLATFORM := android-22

 APP_STL := gnustl_static

-APP_MODULES := layer_utils VkLayer_core_validation VkLayer_device_limits VkLayer_image VkLayer_parameter_validation VkLayer_object_tracker VkLayer_threading VkLayer_swapchain VkLayer_unique_objects

-APP_CPPFLAGS += -std=c++11 -DVK_PROTOTYPES -Wall -Werror -Wno-unused-function -Wno-unused-const-variable

+APP_MODULES := layer_utils VkLayer_core_validation VkLayer_image VkLayer_parameter_validation VkLayer_object_tracker VkLayer_threading VkLayer_swapchain VkLayer_unique_objects VkLayerValidationTests VulkanLayerValidationTests

+APP_CPPFLAGS += -std=c++11 -DVK_PROTOTYPES -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot

 NDK_TOOLCHAIN_VERSION := clang

diff --git a/build-android/res/values/strings.xml b/build-android/res/values/strings.xml
new file mode 100644
index 0000000..8ff71b0
--- /dev/null
+++ b/build-android/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2016 The Android Open Source Project
+
+     Licensed under the Apache 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
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     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 file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="app_name">VulkanLayerValidationTests</string>
+
+</resources>
diff --git a/build-android/shaderc_revision_android b/build-android/shaderc_revision_android
index 8187523..1f7391f 100644
--- a/build-android/shaderc_revision_android
+++ b/build-android/shaderc_revision_android
@@ -1 +1 @@
-4213a472474053f456464b7d00d14adf814ecc44
+master
diff --git a/build-android/spirv-headers_revision_android b/build-android/spirv-headers_revision_android
new file mode 100644
index 0000000..1f7391f
--- /dev/null
+++ b/build-android/spirv-headers_revision_android
@@ -0,0 +1 @@
+master
diff --git a/build-android/spirv-tools_revision_android b/build-android/spirv-tools_revision_android
index 9a829b9..1f7391f 100644
--- a/build-android/spirv-tools_revision_android
+++ b/build-android/spirv-tools_revision_android
@@ -1 +1 @@
-469f0e8fd53b527ad410c46bf18eee327c9256a3
+master
diff --git a/build-android/update_external_sources_android.bat b/build-android/update_external_sources_android.bat
index fd394f4..8f6db22 100755
--- a/build-android/update_external_sources_android.bat
+++ b/build-android/update_external_sources_android.bat
@@ -25,6 +25,7 @@
 set BASE_DIR=%BUILD_DIR%\external
 set GLSLANG_DIR=%BASE_DIR%\glslang
 set SPIRV_TOOLS_DIR=%BASE_DIR%\spirv-tools
+set SPIRV_HEADERS_DIR=%BASE_DIR%\spirv-tools\external\spirv-headers
 set SHADERC_DIR=%BASE_DIR%\shaderc
 
 for %%X in (where.exe) do (set FOUND=%%~$PATH:X)
@@ -78,6 +79,13 @@
    goto:error
 )
 
+if not exist %ANDROID_BUILD_DIR%\spirv-headers_revision_android (
+   echo.
+   echo Missing spirv-headers_revision_android file. Place it in %ANDROID_BUILD_DIR%
+   set errorCode=1
+   goto:error
+)
+
 if not exist %ANDROID_BUILD_DIR%\shaderc_revision_android (
    echo.
    echo Missing shaderc_revision_android file. Place it in %ANDROID_BUILD_DIR%
@@ -87,16 +95,19 @@
 
 set /p GLSLANG_REVISION= < glslang_revision_android
 set /p SPIRV_TOOLS_REVISION= < spirv-tools_revision_android
+set /p SPIRV_HEADERS_REVISION= < spirv-headers_revision_android
 set /p SHADERC_REVISION= < shaderc_revision_android
 echo GLSLANG_REVISION=%GLSLANG_REVISION%
 echo SPIRV_TOOLS_REVISION=%SPIRV_TOOLS_REVISION%
+echo SPIRV_HEADERS_REVISION=%SPIRV_HEADERS_REVISION%
 echo SHADERC_REVISION=%SHADERC_REVISION%
 
 
-echo Creating and/or updating glslang, spirv-tools, shaderc in %BASE_DIR%
+echo Creating and/or updating glslang, spirv-tools, spirv-headers, shaderc in %BASE_DIR%
 
 set sync-glslang=1
 set sync-spirv-tools=1
+set sync-spirv-headers=1
 set sync-shaderc=1
 set build-shaderc=1
 
@@ -125,6 +136,19 @@
    if %errorCode% neq 0 (goto:error)
 )
 
+if %sync-spirv-headers% equ 1 (
+   if exist %SPIRV_HEADERS_DIR% (
+      rd /S /Q %SPIRV_HEADERS_DIR%
+   )
+   if %ERRORLEVEL% neq 0 (goto:error)
+   if not exist %SPIRV_HEADERS_DIR% (
+      call:create_spirv-headers
+   )
+   if %errorCode% neq 0 (goto:error)
+   call:update_spirv-headers
+   if %errorCode% neq 0 (goto:error)
+)
+
 if %sync-shaderc% equ 1 (
    if exist %SHADERC_DIR% (
       rd /S /Q %SHADERC_DIR%
@@ -154,6 +178,8 @@
 :finish
 if not "%cd%\" == "%BUILD_DIR%" ( cd %BUILD_DIR% )
 endlocal
+REM This needs a fix to return error, something like exit %errorCode%
+REM Right now it is returning 0
 goto:eof
 
 
@@ -210,12 +236,37 @@
    )
 goto:eof
 
+:create_spirv-headers
+   echo.
+   echo Creating local spirv-headers repository %SPIRV_HEADERS_DIR%
+   mkdir %SPIRV_HEADERS_DIR%
+   cd %SPIRV_HEADERS_DIR%
+   git clone https://github.com/KhronosGroup/SPIRV-Headers.git .
+   git checkout %SPIRV_HEADERS_REVISION%
+   if not exist %SPIRV_HEADERS_DIR%\include (
+      echo spirv-headers source download failed!
+      set errorCode=1
+   )
+goto:eof
+
+:update_spirv-headers
+   echo.
+   echo Updating %SPIRV_HEADERS_DIR%
+   cd %SPIRV_HEADERS_DIR%
+   git fetch --all
+   git checkout %SPIRV_HEADERS_REVISION%
+   if not exist %SPIRV_HEADERS_DIR%\include (
+      echo spirv-headers source update failed!
+      set errorCode=1
+   )
+goto:eof
+
 :create_shaderc
    echo.
-   echo Creating local shaderc repository %SHADERC_DIR%)
+   echo Creating local shaderc repository %SHADERC_DIR%
    mkdir %SHADERC_DIR%
    cd %SHADERC_DIR%
-   git clone git@github.com:google/shaderc.git .
+   git clone https://github.com/google/shaderc.git .
    git checkout %SHADERC_REVISION%
    if not exist %SHADERC_DIR%\libshaderc (
       echo shaderc source download failed!
diff --git a/build-android/update_external_sources_android.sh b/build-android/update_external_sources_android.sh
index e728d89..f525086 100755
--- a/build-android/update_external_sources_android.sh
+++ b/build-android/update_external_sources_android.sh
@@ -24,6 +24,7 @@
 
 GLSLANG_REVISION=$(cat $ANDROIDBUILDDIR/glslang_revision_android)
 SPIRV_TOOLS_REVISION=$(cat $ANDROIDBUILDDIR/spirv-tools_revision_android)
+SPIRV_HEADERS_REVISION=$(cat $ANDROIDBUILDDIR/spirv-headers_revision_android)
 SHADERC_REVISION=$(cat $ANDROIDBUILDDIR/shaderc_revision_android)
 
 echo "GLSLANG_REVISION=$GLSLANG_REVISION"
@@ -35,7 +36,7 @@
    echo "Creating local glslang repository ($BASEDIR/glslang)."
    mkdir -p $BASEDIR/glslang
    cd $BASEDIR/glslang
-   git clone https://github.com/KhronosGroup/glslang.git .
+   git clone persistent-https://android.git.corp.google.com/platform/external/shaderc/glslang .
    git checkout $GLSLANG_REVISION
 }
 
@@ -51,7 +52,7 @@
    echo "Creating local spirv-tools repository ($BASEDIR/spirv-tools)."
    mkdir -p $BASEDIR/spirv-tools
    cd $BASEDIR/spirv-tools
-   git clone https://github.com/KhronosGroup/SPIRV-Tools.git .
+   git clone persistent-https://android.git.corp.google.com/platform/external/shaderc/spirv-tools .
    git checkout $SPIRV_TOOLS_REVISION
 }
 
@@ -62,11 +63,27 @@
    git checkout $SPIRV_TOOLS_REVISION
 }
 
+function create_spirv-headers () {
+   rm -rf $BASEDIR/spirv-tools/external/spirv-headers
+   echo "Creating local spirv-headers repository ($BASEDIR/spirv-tools/external/spirv-headers)."
+   mkdir -p $BASEDIR/spirv-tools/external/spirv-headers
+   cd $BASEDIR/spirv-tools/external/spirv-headers
+   git clone persistent-https://android.git.corp.google.com/platform/external/shaderc/spirv-headers .
+   git checkout $SPIRV_HEADERS_REVISION
+}
+
+function update_spirv-headers () {
+   echo "Updating $BASEDIR/spirv-tools/external/spirv-headers"
+   cd $BASEDIR/spirv-tools/external/spirv-headers
+   git fetch --all
+   git checkout $SPIRV_HEADERS_REVISION
+}
+
 function create_shaderc () {
    rm -rf $BASEDIR/shaderc
    echo "Creating local shaderc repository ($BASEDIR/shaderc)."
    cd $BASEDIR
-   git clone git@github.com:google/shaderc.git
+   git clone persistent-https://android.git.corp.google.com/platform/external/shaderc/shaderc
    cd shaderc
    git checkout $SHADERC_REVISION
 }
@@ -95,6 +112,11 @@
 fi
 update_spirv-tools
 
+if [ ! -d "$BASEDIR/spirv-tools/external/spirv-headers" -o ! -d "$BASEDIR/spirv-tools/external/spirv-headers/.git" ]; then
+   create_spirv-headers
+fi
+update_spirv-headers
+
 if [ ! -d "$BASEDIR/shaderc" -o ! -d "$BASEDIR/shaderc/.git" ]; then
      create_shaderc
 fi
diff --git a/build_windows_targets.bat b/build_windows_targets.bat
index 3844742..eb13209 100644
--- a/build_windows_targets.bat
+++ b/build_windows_targets.bat
@@ -34,7 +34,7 @@
     if %do_32%==0 (
         if %do_64%==0 (
             echo No valid parameters specified.
-            exit /B 1
+            exit 1
         )
     )
 )
@@ -76,7 +76,7 @@
        echo.
        echo 64-bit Debug build failed!
        popd
-       exit /B 1
+       exit 1
     )   
    
     echo Building 64-bit Release 
@@ -85,7 +85,7 @@
        echo.
        echo 64-bit Release build failed!
        popd
-       exit /B 1
+       exit 1
     )   
     popd
 )
@@ -106,7 +106,7 @@
        echo.
        echo 32-bit Debug build failed!
        popd
-       exit /B 1
+       exit 1
     )   
        
     echo Building 32-bit Release 
@@ -115,8 +115,8 @@
        echo.
        echo 32-bit Release build failed!
        popd
-       exit /B 1
+       exit 1
     )   
     popd
 )
-exit /B 0
+exit 0
diff --git a/cmake/FindWayland.cmake b/cmake/FindWayland.cmake
new file mode 100644
index 0000000..f93218b
--- /dev/null
+++ b/cmake/FindWayland.cmake
@@ -0,0 +1,66 @@
+# Try to find Wayland on a Unix system
+#
+# This will define:
+#
+#   WAYLAND_FOUND       - True if Wayland is found
+#   WAYLAND_LIBRARIES   - Link these to use Wayland
+#   WAYLAND_INCLUDE_DIR - Include directory for Wayland
+#   WAYLAND_DEFINITIONS - Compiler flags for using Wayland
+#
+# In addition the following more fine grained variables will be defined:
+#
+#   WAYLAND_CLIENT_FOUND  WAYLAND_CLIENT_INCLUDE_DIR  WAYLAND_CLIENT_LIBRARIES
+#   WAYLAND_SERVER_FOUND  WAYLAND_SERVER_INCLUDE_DIR  WAYLAND_SERVER_LIBRARIES
+#   WAYLAND_EGL_FOUND     WAYLAND_EGL_INCLUDE_DIR     WAYLAND_EGL_LIBRARIES
+#
+# Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+IF (NOT WIN32)
+  IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES)
+    # In the cache already
+    SET(WAYLAND_FIND_QUIETLY TRUE)
+  ENDIF ()
+
+  # Use pkg-config to get the directories and then use these values
+  # in the FIND_PATH() and FIND_LIBRARY() calls
+  FIND_PACKAGE(PkgConfig)
+  PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
+
+  SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
+
+  FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR  NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
+  FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR  NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
+  FIND_PATH(WAYLAND_EGL_INCLUDE_DIR     NAMES wayland-egl.h    HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
+  FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR  NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
+
+  FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client   HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
+  FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server   HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
+  FIND_LIBRARY(WAYLAND_EGL_LIBRARIES    NAMES wayland-egl      HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
+  FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor   HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
+
+  set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR})
+
+  set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
+
+  list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR)
+
+  include(FindPackageHandleStandardArgs)
+
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT  DEFAULT_MSG  WAYLAND_CLIENT_LIBRARIES  WAYLAND_CLIENT_INCLUDE_DIR)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER  DEFAULT_MSG  WAYLAND_SERVER_LIBRARIES  WAYLAND_SERVER_INCLUDE_DIR)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL     DEFAULT_MSG  WAYLAND_EGL_LIBRARIES     WAYLAND_EGL_INCLUDE_DIR)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR  DEFAULT_MSG  WAYLAND_CURSOR_LIBRARIES  WAYLAND_CURSOR_INCLUDE_DIR)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND         DEFAULT_MSG  WAYLAND_LIBRARIES         WAYLAND_INCLUDE_DIR)
+
+  MARK_AS_ADVANCED(
+        WAYLAND_INCLUDE_DIR         WAYLAND_LIBRARIES
+        WAYLAND_CLIENT_INCLUDE_DIR  WAYLAND_CLIENT_LIBRARIES
+        WAYLAND_SERVER_INCLUDE_DIR  WAYLAND_SERVER_LIBRARIES
+        WAYLAND_EGL_INCLUDE_DIR     WAYLAND_EGL_LIBRARIES
+        WAYLAND_CURSOR_INCLUDE_DIR  WAYLAND_CURSOR_LIBRARIES
+  )
+
+ENDIF ()
diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt
index 7d8681a..26e86fb 100644
--- a/demos/CMakeLists.txt
+++ b/demos/CMakeLists.txt
@@ -1,6 +1,13 @@
 if(NOT WIN32)
-    find_package(XCB REQUIRED)
-    find_package(X11 REQUIRED)
+    if (BUILD_WSI_XCB_SUPPORT)
+        find_package(XCB REQUIRED)
+    endif()
+    if (BUILD_WSI_XLIB_SUPPORT)
+        find_package(X11 REQUIRED)
+    endif()
+    if (BUILD_WSI_WAYLAND_SUPPORT)
+        find_package(Wayland REQUIRED)
+    endif()
 endif()
 
 file(GLOB TEXTURES
@@ -28,8 +35,13 @@
         set (BUILDTGT_DIR build32)
     endif()
 
-    set(CMAKE_C_FLAGS_DEBUG "-MTd")
-    set(CMAKE_C_FLAGS_RELEASE "-MT")
+    # Use static MSVCRT libraries
+    foreach(configuration in CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO
+                             CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+        if(${configuration} MATCHES "/MD")
+            string(REGEX REPLACE "/MD" "/MT" ${configuration} "${${configuration}}")
+        endif()
+    endforeach()
 
     add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/demos/tri-vert.spv
        COMMAND ${GLSLANG_VALIDATOR} -s -V ${PROJECT_SOURCE_DIR}/demos/tri.vert
@@ -75,12 +87,21 @@
 endif()
 
 if(NOT WIN32)
-    include_directories (
-       ${XCB_INCLUDE_DIRS}
-       ${X11_INCLUDE_DIRS}
-       "${PROJECT_SOURCE_DIR}/icd/common"
-       )
-    link_libraries(${XCB_LIBRARIES} ${X11_LIBRARIES} vulkan m)
+    if(BUILD_WSI_XCB_SUPPORT)
+        include_directories(${XCB_INCLUDE_DIRS})
+        link_libraries(${XCB_LIBRARIES})
+    endif()
+    if(BUILD_WSI_XLIB_SUPPORT)
+        include_directories(${X11_INCLUDE_DIRS})
+        link_libraries(${X11_LIBRARIES})
+    endif()
+    if(BUILD_WSI_WAYLAND_SUPPORT)
+        include_directories(${WAYLAND_CLIENT_INCLUDE_DIR})
+        link_libraries(${WAYLAND_CLIENT_LIBRARIES})
+    endif()
+
+    include_directories ("${PROJECT_SOURCE_DIR}/icd/common")
+    link_libraries(vulkan m)
 endif()
 if(WIN32)
     include_directories (
diff --git a/demos/android/include/lunarg.ppm.h b/demos/android/include/lunarg.ppm.h
index 9ee127a..f18bea9 100644
--- a/demos/android/include/lunarg.ppm.h
+++ b/demos/android/include/lunarg.ppm.h
@@ -1,4 +1,4 @@
-unsigned char ___lunarg_ppm[] = {
+unsigned char lunarg_ppm[] = {
   0x50, 0x36, 0x0a, 0x32, 0x35, 0x36, 0x20, 0x32, 0x35, 0x36, 0x0a, 0x32,
   0x35, 0x35, 0x0a, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -3421,72 +3421,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
@@ -3548,6 +3483,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
@@ -3611,215 +3547,150 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -3865,23 +3736,88 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -3929,88 +3865,152 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -4056,28 +4056,28 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -4122,24 +4122,24 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -4183,93 +4183,29 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
   0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
   0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
   0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
   0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -4310,224 +4246,224 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
   0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -4569,158 +4505,222 @@
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-  0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82,
-  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
   0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
   0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -4760,95 +4760,31 @@
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
   0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+  0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85,
   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
   0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-  0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-  0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -4869,6 +4805,60 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x69, 0x74, 0x75, 0x33, 0x6d, 0x75,
+  0x14, 0x65, 0x71, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
+  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
+  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
+  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
+  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
+  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6d,
+  0x0f, 0x62, 0x6d, 0x0f, 0x62, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d,
+  0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d,
+  0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6c,
+  0x0f, 0x61, 0x6c, 0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c,
+  0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c,
+  0x0f, 0x60, 0x6b, 0x0f, 0x5f, 0x6b, 0x0f, 0x5f, 0x6b, 0x0f, 0x5f, 0x6b,
+  0x0f, 0x5f, 0x6b, 0x0f, 0x5f, 0x6b, 0x0f, 0x5f, 0x6a, 0x0f, 0x5f, 0x6a,
+  0x0f, 0x5e, 0x6a, 0x0f, 0x5e, 0x69, 0x0f, 0x5e, 0x69, 0x0f, 0x5e, 0x69,
+  0x0f, 0x5d, 0x69, 0x0d, 0x5d, 0x68, 0x0d, 0x5d, 0x68, 0x0d, 0x5d, 0x68,
+  0x0d, 0x5c, 0x68, 0x0d, 0x5c, 0x67, 0x0d, 0x5c, 0x67, 0x0d, 0x5c, 0x67,
+  0x0d, 0x5b, 0x66, 0x0d, 0x5b, 0x66, 0x0d, 0x5b, 0x66, 0x0d, 0x5a, 0x65,
+  0x0d, 0x5a, 0x65, 0x0d, 0x59, 0x64, 0x0e, 0x59, 0x64, 0x0e, 0x59, 0x63,
+  0x0e, 0x59, 0x63, 0x0e, 0x59, 0x62, 0x0e, 0x59, 0x62, 0x0e, 0x57, 0x61,
+  0x0e, 0x58, 0x60, 0x0f, 0x57, 0x5f, 0x0f, 0x57, 0x5f, 0x0e, 0x56, 0x5f,
+  0x0d, 0x56, 0x5f, 0x0d, 0x55, 0x5f, 0x0d, 0x54, 0x5e, 0x0d, 0x54, 0x5d,
+  0x0e, 0x53, 0x5e, 0x0e, 0x53, 0x5d, 0x0e, 0x52, 0x5c, 0x0e, 0x52, 0x5c,
+  0x0e, 0x51, 0x5b, 0x0e, 0x52, 0x5a, 0x0e, 0x51, 0x5a, 0x0e, 0x4f, 0x58,
+  0x0e, 0x4f, 0x57, 0x0e, 0x4e, 0x56, 0x0e, 0x4d, 0x56, 0x0f, 0x4c, 0x56,
+  0x0f, 0x4c, 0x55, 0x0d, 0x4b, 0x53, 0x0d, 0x4a, 0x53, 0x0d, 0x4a, 0x51,
+  0x0e, 0x4a, 0x51, 0x0e, 0x49, 0x51, 0x0d, 0x48, 0x50, 0x0d, 0x47, 0x4f,
+  0x0d, 0x46, 0x4e, 0x0d, 0x46, 0x4d, 0x0d, 0x44, 0x4b, 0x0d, 0x43, 0x4b,
+  0x0d, 0x42, 0x4b, 0x0d, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0c, 0x3e, 0x45, 0x0c, 0x3d, 0x43, 0x09, 0x37, 0x3f,
+  0x41, 0x69, 0x6e, 0xd7, 0xe4, 0xe6, 0xc4, 0xd7, 0xda, 0x5b, 0x91, 0x98,
+  0x46, 0x81, 0x8a, 0x46, 0x80, 0x89, 0x46, 0x80, 0x89, 0x46, 0x80, 0x89,
+  0x45, 0x80, 0x89, 0x45, 0x80, 0x89, 0x43, 0x7e, 0x88, 0x43, 0x7d, 0x86,
+  0x43, 0x7d, 0x86, 0x42, 0x7c, 0x85, 0x41, 0x7b, 0x84, 0x41, 0x7b, 0x84,
+  0x40, 0x7a, 0x84, 0x3f, 0x79, 0x83, 0x3e, 0x78, 0x82, 0x3d, 0x78, 0x81,
+  0x3c, 0x77, 0x80, 0x3b, 0x76, 0x7f, 0x3b, 0x76, 0x7f, 0x3a, 0x74, 0x7d,
+  0x39, 0x74, 0x7d, 0x38, 0x71, 0x7b, 0x37, 0x71, 0x7b, 0x36, 0x70, 0x7a,
+  0x35, 0x6f, 0x79, 0x34, 0x6f, 0x77, 0x33, 0x6f, 0x77, 0x32, 0x6c, 0x76,
+  0x32, 0x6b, 0x75, 0x31, 0x6b, 0x75, 0x2f, 0x69, 0x73, 0x2f, 0x69, 0x71,
+  0x2e, 0x68, 0x71, 0x2d, 0x68, 0x70, 0x2d, 0x67, 0x6f, 0x2c, 0x65, 0x6f,
+  0x2a, 0x64, 0x6d, 0x2a, 0x64, 0x6c, 0x29, 0x63, 0x6c, 0x29, 0x62, 0x6b,
+  0x28, 0x62, 0x6a, 0x27, 0x60, 0x69, 0x27, 0x60, 0x69, 0x27, 0x60, 0x69,
+  0x26, 0x5e, 0x67, 0x26, 0x5e, 0x67, 0x26, 0x5e, 0x65, 0x25, 0x5d, 0x64,
+  0x25, 0x5d, 0x64, 0x24, 0x5b, 0x63, 0x23, 0x5a, 0x63, 0x23, 0x59, 0x63,
+  0x23, 0x59, 0x62, 0x23, 0x58, 0x61, 0x22, 0x58, 0x61, 0x22, 0x57, 0x60,
+  0x22, 0x57, 0x60, 0x22, 0x56, 0x5f, 0x22, 0x56, 0x5f, 0x22, 0x55, 0x5d,
+  0x21, 0x55, 0x5d, 0x20, 0x53, 0x5b, 0x20, 0x52, 0x5b, 0x20, 0x52, 0x5b,
+  0x20, 0x52, 0x5b, 0x20, 0x52, 0x5a, 0x1f, 0x51, 0x59, 0x1f, 0x51, 0x59,
+  0x1f, 0x50, 0x58, 0x1e, 0x4f, 0x57, 0x1e, 0x4f, 0x57, 0x1e, 0x4d, 0x55,
+  0x1e, 0x4d, 0x55, 0x1e, 0x4d, 0x54, 0x1e, 0x4c, 0x54, 0x1d, 0x4c, 0x53,
+  0x1d, 0x4b, 0x52, 0x1c, 0x4a, 0x51, 0x1d, 0x4a, 0x51, 0x1d, 0x49, 0x50,
+  0x1d, 0x48, 0x4f, 0x1c, 0x47, 0x4e, 0x1c, 0x47, 0x4e, 0x1c, 0x46, 0x4d,
+  0x1c, 0x46, 0x4c, 0x1b, 0x45, 0x4b, 0x1b, 0x44, 0x4b, 0x1b, 0x43, 0x4a,
+  0x1b, 0x43, 0x49, 0x26, 0x4c, 0x52, 0x49, 0x62, 0x67, 0x72, 0x73, 0x73,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -4879,125 +4869,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88,
-  0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-  0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-  0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
-  0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
-  0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x5b, 0x73, 0x76,
-  0x39, 0x6e, 0x76, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
-  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
-  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
-  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
-  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
-  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
-  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
-  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
-  0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74,
-  0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74,
-  0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x73, 0x2d, 0x6b, 0x73,
-  0x2d, 0x6b, 0x73, 0x2d, 0x6b, 0x73, 0x2c, 0x6a, 0x73, 0x2c, 0x69, 0x72,
-  0x2c, 0x69, 0x72, 0x2c, 0x69, 0x72, 0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72,
-  0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72,
-  0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72, 0x2d, 0x69, 0x71, 0x2d, 0x69, 0x71,
-  0x2c, 0x68, 0x71, 0x2c, 0x68, 0x71, 0x2c, 0x68, 0x72, 0x2c, 0x68, 0x72,
-  0x2c, 0x68, 0x70, 0x2c, 0x68, 0x70, 0x2c, 0x67, 0x70, 0x2c, 0x67, 0x70,
-  0x2c, 0x67, 0x70, 0x2d, 0x67, 0x70, 0x2d, 0x67, 0x6f, 0x2c, 0x67, 0x6f,
-  0x2d, 0x67, 0x6f, 0x2d, 0x66, 0x6f, 0x2d, 0x66, 0x6f, 0x2e, 0x67, 0x6f,
-  0x2e, 0x67, 0x6f, 0x2e, 0x67, 0x6f, 0x2e, 0x67, 0x6f, 0x2d, 0x67, 0x6f,
-  0x2e, 0x66, 0x6f, 0x2e, 0x66, 0x6e, 0x2e, 0x66, 0x6e, 0x2e, 0x66, 0x6e,
-  0x2f, 0x66, 0x6d, 0x2e, 0x65, 0x6e, 0x2f, 0x65, 0x6e, 0x2f, 0x65, 0x6e,
-  0x30, 0x65, 0x6d, 0x2f, 0x65, 0x6c, 0x30, 0x65, 0x6c, 0x31, 0x65, 0x6c,
-  0x30, 0x64, 0x6c, 0x30, 0x64, 0x6b, 0x31, 0x64, 0x6c, 0x31, 0x64, 0x6b,
-  0x31, 0x64, 0x6b, 0x31, 0x63, 0x6b, 0x31, 0x63, 0x6a, 0x31, 0x62, 0x6a,
-  0x31, 0x62, 0x6a, 0x31, 0x62, 0x69, 0x31, 0x61, 0x69, 0x32, 0x61, 0x69,
-  0x31, 0x61, 0x69, 0x31, 0x61, 0x67, 0x31, 0x60, 0x66, 0x31, 0x60, 0x66,
-  0x31, 0x5f, 0x66, 0x31, 0x5f, 0x65, 0x31, 0x5f, 0x65, 0x30, 0x5e, 0x64,
-  0x30, 0x5d, 0x63, 0x30, 0x5d, 0x63, 0x30, 0x5b, 0x62, 0x2c, 0x56, 0x5d,
-  0x69, 0x89, 0x8d, 0xaf, 0xc2, 0xc4, 0x9d, 0xb4, 0xb7, 0x67, 0x89, 0x8f,
-  0x64, 0x87, 0x8c, 0x64, 0x87, 0x8c, 0x63, 0x87, 0x8c, 0x63, 0x87, 0x8c,
-  0x62, 0x85, 0x8b, 0x62, 0x85, 0x8b, 0x62, 0x84, 0x8a, 0x62, 0x84, 0x8a,
-  0x61, 0x84, 0x8a, 0x60, 0x83, 0x88, 0x60, 0x83, 0x88, 0x5f, 0x83, 0x88,
-  0x5e, 0x81, 0x87, 0x5e, 0x81, 0x86, 0x5d, 0x80, 0x86, 0x5c, 0x7f, 0x85,
-  0x5b, 0x7f, 0x85, 0x5a, 0x7e, 0x84, 0x59, 0x7d, 0x82, 0x59, 0x7c, 0x82,
-  0x58, 0x7c, 0x82, 0x57, 0x7b, 0x81, 0x57, 0x7b, 0x80, 0x55, 0x7a, 0x7f,
-  0x54, 0x79, 0x7e, 0x54, 0x77, 0x7d, 0x54, 0x77, 0x7d, 0x52, 0x77, 0x7c,
-  0x51, 0x76, 0x7b, 0x50, 0x75, 0x7b, 0x4f, 0x74, 0x79, 0x4f, 0x73, 0x79,
-  0x4e, 0x72, 0x78, 0x4d, 0x72, 0x78, 0x4c, 0x71, 0x77, 0x4b, 0x70, 0x76,
-  0x4b, 0x70, 0x76, 0x4a, 0x70, 0x75, 0x49, 0x6f, 0x75, 0x49, 0x6e, 0x74,
-  0x48, 0x6d, 0x73, 0x47, 0x6c, 0x71, 0x47, 0x6c, 0x71, 0x46, 0x6b, 0x71,
-  0x46, 0x6b, 0x71, 0x45, 0x6a, 0x70, 0x45, 0x6a, 0x70, 0x45, 0x6a, 0x70,
-  0x45, 0x68, 0x6e, 0x45, 0x68, 0x6e, 0x45, 0x68, 0x6e, 0x44, 0x68, 0x6d,
-  0x44, 0x68, 0x6d, 0x43, 0x67, 0x6c, 0x43, 0x67, 0x6c, 0x42, 0x65, 0x6c,
-  0x42, 0x65, 0x6c, 0x42, 0x65, 0x6b, 0x42, 0x65, 0x6b, 0x41, 0x65, 0x6b,
-  0x41, 0x64, 0x6a, 0x41, 0x64, 0x6a, 0x40, 0x63, 0x69, 0x40, 0x63, 0x69,
-  0x40, 0x63, 0x69, 0x3f, 0x63, 0x68, 0x3f, 0x63, 0x68, 0x3f, 0x62, 0x68,
-  0x3f, 0x61, 0x67, 0x3f, 0x61, 0x67, 0x3f, 0x61, 0x67, 0x3f, 0x60, 0x67,
-  0x3e, 0x60, 0x65, 0x3e, 0x60, 0x65, 0x3e, 0x60, 0x65, 0x3e, 0x5f, 0x65,
-  0x3e, 0x5f, 0x65, 0x3d, 0x5f, 0x64, 0x3d, 0x5f, 0x64, 0x3d, 0x5e, 0x64,
-  0x3d, 0x5e, 0x63, 0x3d, 0x5e, 0x63, 0x3d, 0x5d, 0x63, 0x3d, 0x5d, 0x63,
-  0x3c, 0x5c, 0x62, 0x3b, 0x5c, 0x61, 0x3c, 0x5b, 0x60, 0x3c, 0x5b, 0x60,
-  0x3c, 0x5b, 0x60, 0x4a, 0x63, 0x67, 0x67, 0x70, 0x71, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x6f, 0x74, 0x75, 0x23, 0x6a, 0x74, 0x07, 0x5d, 0x69,
+  0x75, 0x75, 0x75, 0x56, 0x72, 0x76, 0x0c, 0x61, 0x6d, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
@@ -5009,48 +4881,49 @@
   0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
   0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
   0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x57, 0x63,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
   0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
   0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61, 0x06, 0x55, 0x61,
   0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60, 0x06, 0x54, 0x5f,
   0x06, 0x54, 0x5f, 0x06, 0x53, 0x5f, 0x05, 0x53, 0x5e, 0x05, 0x53, 0x5e,
   0x05, 0x53, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5c, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x4f, 0x5a, 0x05, 0x4f, 0x5a,
+  0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a, 0x05, 0x4f, 0x5a,
   0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58, 0x05, 0x4e, 0x58, 0x05, 0x4d, 0x57,
   0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55,
   0x05, 0x4a, 0x54, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53, 0x05, 0x48, 0x51,
   0x05, 0x48, 0x51, 0x05, 0x47, 0x50, 0x05, 0x46, 0x50, 0x05, 0x46, 0x4f,
-  0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4c, 0x04, 0x42, 0x4b,
-  0x04, 0x42, 0x4a, 0x04, 0x41, 0x49, 0x04, 0x40, 0x49, 0x04, 0x3f, 0x48,
-  0x04, 0x3e, 0x47, 0x04, 0x3d, 0x45, 0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43,
-  0x04, 0x3a, 0x42, 0x04, 0x39, 0x41, 0x04, 0x38, 0x40, 0x04, 0x38, 0x3f,
-  0x04, 0x36, 0x3e, 0x04, 0x35, 0x3d, 0x04, 0x34, 0x3b, 0x03, 0x33, 0x3a,
-  0x03, 0x32, 0x38, 0x03, 0x31, 0x38, 0x03, 0x30, 0x36, 0x03, 0x2e, 0x35,
-  0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32, 0x03, 0x2b, 0x31, 0x01, 0x28, 0x2e,
-  0x08, 0x30, 0x35, 0x9d, 0xb2, 0xb5, 0xff, 0xff, 0xff, 0xac, 0xca, 0xce,
-  0x40, 0x85, 0x8f, 0x3c, 0x82, 0x8d, 0x3c, 0x81, 0x8c, 0x3c, 0x81, 0x8c,
-  0x3c, 0x80, 0x8b, 0x3b, 0x7f, 0x8a, 0x3a, 0x7e, 0x89, 0x3a, 0x7e, 0x88,
-  0x39, 0x7d, 0x88, 0x38, 0x7c, 0x86, 0x37, 0x7b, 0x86, 0x36, 0x7a, 0x85,
-  0x34, 0x79, 0x84, 0x33, 0x78, 0x83, 0x32, 0x77, 0x82, 0x31, 0x76, 0x80,
-  0x31, 0x75, 0x80, 0x30, 0x74, 0x7e, 0x2f, 0x73, 0x7e, 0x2e, 0x71, 0x7c,
-  0x2d, 0x70, 0x7b, 0x2c, 0x6f, 0x7a, 0x2a, 0x6e, 0x79, 0x28, 0x6d, 0x77,
-  0x27, 0x6b, 0x75, 0x26, 0x69, 0x74, 0x26, 0x69, 0x73, 0x25, 0x68, 0x72,
-  0x24, 0x67, 0x71, 0x23, 0x65, 0x70, 0x21, 0x63, 0x6f, 0x20, 0x63, 0x6d,
-  0x1f, 0x61, 0x6d, 0x1e, 0x61, 0x6b, 0x1d, 0x60, 0x6a, 0x1c, 0x5e, 0x69,
-  0x1b, 0x5d, 0x67, 0x1b, 0x5c, 0x66, 0x1a, 0x5b, 0x66, 0x18, 0x59, 0x63,
-  0x18, 0x58, 0x63, 0x18, 0x57, 0x61, 0x17, 0x56, 0x60, 0x17, 0x55, 0x60,
-  0x16, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
-  0x13, 0x50, 0x5a, 0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58,
-  0x12, 0x4c, 0x56, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
-  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50,
-  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0e, 0x43, 0x4b,
-  0x0e, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x47, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4c, 0x04, 0x43, 0x4b,
+  0x04, 0x42, 0x4b, 0x04, 0x41, 0x49, 0x04, 0x40, 0x49, 0x04, 0x3f, 0x48,
+  0x04, 0x3e, 0x47, 0x04, 0x3d, 0x45, 0x04, 0x3d, 0x45, 0x04, 0x3c, 0x44,
+  0x04, 0x3b, 0x43, 0x04, 0x39, 0x41, 0x04, 0x38, 0x40, 0x04, 0x38, 0x3f,
+  0x04, 0x36, 0x3e, 0x04, 0x35, 0x3d, 0x04, 0x34, 0x3c, 0x04, 0x33, 0x3a,
+  0x03, 0x32, 0x39, 0x03, 0x31, 0x38, 0x03, 0x30, 0x36, 0x03, 0x2f, 0x35,
+  0x03, 0x2e, 0x34, 0x03, 0x2c, 0x32, 0x03, 0x2b, 0x31, 0x03, 0x29, 0x2f,
+  0x00, 0x25, 0x2a, 0x5a, 0x7a, 0x7e, 0xff, 0xff, 0xff, 0xdc, 0xe9, 0xeb,
+  0x52, 0x90, 0x9a, 0x38, 0x7f, 0x8a, 0x38, 0x7f, 0x8a, 0x37, 0x7e, 0x89,
+  0x37, 0x7e, 0x89, 0x36, 0x7c, 0x88, 0x36, 0x7c, 0x88, 0x35, 0x7b, 0x86,
+  0x34, 0x7a, 0x85, 0x34, 0x7a, 0x84, 0x33, 0x79, 0x83, 0x32, 0x77, 0x83,
+  0x31, 0x77, 0x81, 0x30, 0x75, 0x81, 0x30, 0x75, 0x80, 0x2f, 0x74, 0x7e,
+  0x2e, 0x73, 0x7e, 0x2d, 0x72, 0x7c, 0x2c, 0x71, 0x7c, 0x2b, 0x70, 0x7a,
+  0x2a, 0x6e, 0x79, 0x29, 0x6d, 0x78, 0x27, 0x6d, 0x77, 0x26, 0x6b, 0x76,
+  0x26, 0x6a, 0x75, 0x25, 0x69, 0x73, 0x24, 0x68, 0x73, 0x23, 0x67, 0x71,
+  0x22, 0x65, 0x70, 0x21, 0x64, 0x6f, 0x1f, 0x62, 0x6d, 0x1e, 0x61, 0x6c,
+  0x1d, 0x60, 0x6b, 0x1c, 0x5f, 0x6a, 0x1c, 0x5f, 0x6a, 0x1b, 0x5e, 0x68,
+  0x1a, 0x5c, 0x67, 0x19, 0x5a, 0x65, 0x19, 0x5a, 0x65, 0x18, 0x59, 0x63,
+  0x18, 0x59, 0x62, 0x17, 0x57, 0x61, 0x17, 0x56, 0x61, 0x16, 0x55, 0x5f,
+  0x16, 0x54, 0x5e, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x50, 0x5a,
+  0x13, 0x50, 0x5a, 0x13, 0x4f, 0x59, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57,
+  0x12, 0x4c, 0x56, 0x11, 0x4b, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
+  0x10, 0x4a, 0x53, 0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50,
+  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
+  0x0e, 0x43, 0x4b, 0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48,
+  0x0d, 0x3f, 0x47, 0x0d, 0x3e, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x30, 0x36, 0x0a, 0x2e, 0x34,
-  0x0a, 0x2d, 0x32, 0x0a, 0x2c, 0x32, 0x12, 0x37, 0x3e, 0x3e, 0x5c, 0x61,
+  0x0c, 0x38, 0x3f, 0x0c, 0x38, 0x3e, 0x0c, 0x37, 0x3d, 0x0b, 0x36, 0x3c,
+  0x0b, 0x35, 0x3c, 0x0b, 0x34, 0x3b, 0x0b, 0x33, 0x3a, 0x0b, 0x32, 0x39,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x0a, 0x2d, 0x33, 0x0a, 0x2c, 0x32, 0x09, 0x2b, 0x31, 0x21, 0x46, 0x4c,
+  0x69, 0x70, 0x71, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -5060,8 +4933,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x73, 0x75, 0x75, 0x19, 0x67, 0x72, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x63, 0x73, 0x76, 0x0b, 0x60, 0x6d, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
@@ -5091,21 +4963,85 @@
   0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x00, 0x26, 0x2c, 0x0b, 0x31, 0x37, 0xad, 0xbf, 0xc2, 0xff, 0xff, 0xff,
-  0xb4, 0xcf, 0xd4, 0x44, 0x87, 0x92, 0x40, 0x84, 0x8f, 0x40, 0x84, 0x8f,
-  0x3e, 0x83, 0x8e, 0x3d, 0x82, 0x8d, 0x3d, 0x81, 0x8c, 0x3c, 0x81, 0x8b,
-  0x3c, 0x80, 0x8a, 0x3b, 0x7f, 0x8a, 0x3a, 0x7e, 0x89, 0x39, 0x7d, 0x88,
-  0x38, 0x7c, 0x87, 0x37, 0x7b, 0x86, 0x35, 0x7a, 0x84, 0x34, 0x78, 0x84,
-  0x33, 0x78, 0x82, 0x32, 0x77, 0x82, 0x31, 0x76, 0x80, 0x30, 0x74, 0x7e,
-  0x2f, 0x73, 0x7e, 0x2e, 0x71, 0x7c, 0x2d, 0x71, 0x7c, 0x2b, 0x6f, 0x7a,
-  0x29, 0x6e, 0x78, 0x28, 0x6d, 0x77, 0x27, 0x6c, 0x76, 0x26, 0x6a, 0x75,
-  0x26, 0x69, 0x74, 0x24, 0x68, 0x72, 0x23, 0x66, 0x70, 0x22, 0x65, 0x70,
+  0x01, 0x29, 0x2f, 0x00, 0x23, 0x29, 0x69, 0x87, 0x8b, 0xff, 0xff, 0xff,
+  0xe0, 0xec, 0xed, 0x55, 0x93, 0x9c, 0x3b, 0x81, 0x8c, 0x3b, 0x81, 0x8b,
+  0x3a, 0x81, 0x8b, 0x39, 0x7f, 0x8a, 0x39, 0x7e, 0x89, 0x38, 0x7e, 0x89,
+  0x37, 0x7d, 0x87, 0x37, 0x7c, 0x87, 0x36, 0x7c, 0x87, 0x35, 0x7b, 0x85,
+  0x34, 0x7a, 0x85, 0x33, 0x79, 0x83, 0x31, 0x77, 0x82, 0x31, 0x76, 0x81,
+  0x30, 0x75, 0x80, 0x2f, 0x75, 0x7f, 0x2e, 0x73, 0x7e, 0x2d, 0x72, 0x7c,
+  0x2c, 0x71, 0x7c, 0x2b, 0x70, 0x7a, 0x2a, 0x6f, 0x7a, 0x28, 0x6d, 0x78,
+  0x26, 0x6c, 0x76, 0x26, 0x6b, 0x76, 0x25, 0x6a, 0x74, 0x24, 0x68, 0x74,
+  0x23, 0x67, 0x72, 0x22, 0x66, 0x71, 0x21, 0x65, 0x6f, 0x20, 0x64, 0x6e,
+  0x1f, 0x62, 0x6e, 0x1e, 0x62, 0x6d, 0x1d, 0x61, 0x6c, 0x1c, 0x5f, 0x6b,
+  0x1b, 0x5f, 0x69, 0x1a, 0x5d, 0x68, 0x1a, 0x5d, 0x68, 0x19, 0x5b, 0x66,
+  0x19, 0x5a, 0x64, 0x18, 0x5a, 0x63, 0x17, 0x58, 0x63, 0x17, 0x58, 0x62,
+  0x16, 0x56, 0x60, 0x16, 0x55, 0x60, 0x15, 0x54, 0x5f, 0x15, 0x54, 0x5e,
+  0x14, 0x52, 0x5c, 0x14, 0x52, 0x5c, 0x13, 0x51, 0x5b, 0x12, 0x4f, 0x59,
+  0x12, 0x4e, 0x58, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57, 0x11, 0x4c, 0x56,
+  0x11, 0x4c, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
+  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x0f, 0x46, 0x4f, 0x0f, 0x46, 0x4e,
+  0x0e, 0x45, 0x4e, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
+  0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x31, 0x37, 0x0a, 0x2f, 0x35, 0x09, 0x28, 0x2d,
+  0x20, 0x46, 0x4c, 0x73, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x24, 0x6a, 0x74, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2b, 0x31, 0x01, 0x27, 0x2d, 0x01, 0x26, 0x2c, 0x80, 0x9a, 0x9d,
+  0xff, 0xff, 0xff, 0xe1, 0xec, 0xed, 0x58, 0x94, 0x9d, 0x3e, 0x83, 0x8e,
+  0x3c, 0x82, 0x8d, 0x3c, 0x81, 0x8c, 0x3c, 0x80, 0x8b, 0x3b, 0x7f, 0x8a,
+  0x3b, 0x7f, 0x8a, 0x3a, 0x7e, 0x89, 0x39, 0x7d, 0x88, 0x38, 0x7d, 0x87,
+  0x37, 0x7b, 0x86, 0x36, 0x7b, 0x85, 0x34, 0x79, 0x84, 0x33, 0x78, 0x83,
+  0x32, 0x77, 0x82, 0x31, 0x76, 0x81, 0x30, 0x74, 0x7f, 0x2f, 0x73, 0x7e,
+  0x2e, 0x72, 0x7d, 0x2d, 0x71, 0x7c, 0x2c, 0x70, 0x7b, 0x2a, 0x6e, 0x79,
+  0x28, 0x6d, 0x77, 0x27, 0x6c, 0x77, 0x26, 0x6b, 0x75, 0x26, 0x6a, 0x75,
+  0x25, 0x68, 0x73, 0x24, 0x68, 0x72, 0x23, 0x66, 0x70, 0x21, 0x65, 0x6f,
   0x21, 0x64, 0x6f, 0x1f, 0x63, 0x6d, 0x1e, 0x61, 0x6d, 0x1d, 0x60, 0x6b,
-  0x1c, 0x5f, 0x6a, 0x1c, 0x5e, 0x69, 0x1b, 0x5e, 0x68, 0x1a, 0x5c, 0x67,
-  0x19, 0x5a, 0x65, 0x18, 0x5a, 0x64, 0x18, 0x59, 0x63, 0x17, 0x58, 0x62,
-  0x17, 0x57, 0x61, 0x16, 0x55, 0x60, 0x16, 0x54, 0x5f, 0x15, 0x54, 0x5e,
+  0x1c, 0x5f, 0x6a, 0x1b, 0x5e, 0x68, 0x1a, 0x5d, 0x68, 0x1a, 0x5c, 0x67,
+  0x19, 0x5a, 0x65, 0x18, 0x5a, 0x63, 0x18, 0x59, 0x63, 0x17, 0x58, 0x62,
+  0x16, 0x56, 0x60, 0x16, 0x55, 0x60, 0x15, 0x54, 0x5f, 0x15, 0x54, 0x5e,
   0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x51, 0x5b, 0x13, 0x50, 0x5a,
-  0x13, 0x4f, 0x59, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
+  0x12, 0x4e, 0x58, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
   0x11, 0x4c, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x0f, 0x46, 0x4e,
   0x0e, 0x45, 0x4e, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
@@ -5114,8 +5050,8 @@
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2d, 0x32, 0x09, 0x29, 0x2f,
-  0x36, 0x57, 0x5c, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2d, 0x33,
+  0x09, 0x29, 0x2e, 0x45, 0x60, 0x64, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -5125,7 +5061,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x37, 0x6d, 0x76, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x0c, 0x61, 0x6d, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
@@ -5155,20 +5091,20 @@
   0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2b, 0x31, 0x00, 0x24, 0x2a, 0x12, 0x36, 0x3b, 0xc7, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xb6, 0xd0, 0xd5, 0x47, 0x88, 0x93, 0x43, 0x86, 0x90,
-  0x41, 0x85, 0x90, 0x41, 0x84, 0x8f, 0x40, 0x83, 0x8e, 0x3f, 0x82, 0x8d,
-  0x3f, 0x82, 0x8c, 0x3e, 0x81, 0x8c, 0x3c, 0x80, 0x8b, 0x3c, 0x7f, 0x89,
-  0x3b, 0x7e, 0x89, 0x3a, 0x7d, 0x87, 0x38, 0x7c, 0x86, 0x37, 0x7a, 0x85,
-  0x36, 0x7a, 0x84, 0x34, 0x78, 0x83, 0x33, 0x77, 0x81, 0x32, 0x75, 0x80,
-  0x31, 0x74, 0x7f, 0x30, 0x73, 0x7d, 0x2f, 0x72, 0x7d, 0x2d, 0x70, 0x7b,
-  0x2b, 0x6f, 0x79, 0x2a, 0x6e, 0x79, 0x29, 0x6d, 0x77, 0x27, 0x6b, 0x76,
-  0x26, 0x69, 0x74, 0x26, 0x69, 0x73, 0x25, 0x67, 0x71, 0x24, 0x67, 0x71,
-  0x23, 0x65, 0x70, 0x20, 0x64, 0x6e, 0x1f, 0x62, 0x6d, 0x1e, 0x61, 0x6c,
-  0x1e, 0x61, 0x6b, 0x1d, 0x5f, 0x69, 0x1c, 0x5e, 0x69, 0x1b, 0x5d, 0x67,
-  0x1a, 0x5b, 0x66, 0x18, 0x5a, 0x64, 0x18, 0x59, 0x64, 0x18, 0x59, 0x62,
-  0x17, 0x57, 0x61, 0x17, 0x56, 0x61, 0x16, 0x54, 0x5f, 0x16, 0x54, 0x5e,
-  0x15, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x50, 0x5a,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x00, 0x25, 0x2a, 0x06, 0x2b, 0x2f,
+  0xa4, 0xb8, 0xba, 0xff, 0xff, 0xff, 0xde, 0xe9, 0xeb, 0x56, 0x92, 0x9b,
+  0x3f, 0x84, 0x8f, 0x3f, 0x83, 0x8e, 0x3e, 0x82, 0x8d, 0x3e, 0x82, 0x8d,
+  0x3d, 0x81, 0x8b, 0x3c, 0x80, 0x8b, 0x3c, 0x7f, 0x8a, 0x3b, 0x7f, 0x89,
+  0x3a, 0x7d, 0x88, 0x39, 0x7d, 0x87, 0x37, 0x7b, 0x85, 0x35, 0x79, 0x84,
+  0x34, 0x78, 0x83, 0x33, 0x78, 0x82, 0x32, 0x76, 0x81, 0x31, 0x74, 0x7f,
+  0x30, 0x74, 0x7e, 0x2f, 0x72, 0x7d, 0x2e, 0x71, 0x7c, 0x2c, 0x6f, 0x7a,
+  0x2a, 0x6f, 0x79, 0x29, 0x6d, 0x78, 0x28, 0x6d, 0x77, 0x26, 0x6a, 0x75,
+  0x26, 0x69, 0x74, 0x25, 0x68, 0x72, 0x24, 0x67, 0x71, 0x23, 0x66, 0x70,
+  0x22, 0x64, 0x70, 0x20, 0x64, 0x6e, 0x1f, 0x62, 0x6d, 0x1e, 0x61, 0x6c,
+  0x1d, 0x60, 0x6a, 0x1c, 0x5e, 0x69, 0x1b, 0x5e, 0x68, 0x1a, 0x5c, 0x67,
+  0x1a, 0x5b, 0x66, 0x18, 0x5a, 0x64, 0x18, 0x59, 0x63, 0x18, 0x59, 0x62,
+  0x17, 0x57, 0x61, 0x16, 0x55, 0x60, 0x16, 0x54, 0x5f, 0x15, 0x54, 0x5e,
+  0x15, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x13, 0x51, 0x5b, 0x13, 0x50, 0x5a,
   0x13, 0x4f, 0x59, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
   0x12, 0x4c, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
@@ -5178,8 +5114,8 @@
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x30, 0x36, 0x0a, 0x2d, 0x32,
-  0x0a, 0x2e, 0x34, 0x56, 0x68, 0x6b, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x29, 0x2e, 0x23, 0x49, 0x4f, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -5189,7 +5125,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x11, 0x64, 0x70, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
@@ -5219,20 +5155,84 @@
   0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x00, 0x22, 0x27, 0x1c, 0x41, 0x46,
-  0xde, 0xe5, 0xe6, 0xff, 0xff, 0xff, 0xb3, 0xce, 0xd2, 0x46, 0x88, 0x92,
-  0x45, 0x88, 0x92, 0x45, 0x87, 0x91, 0x43, 0x85, 0x8f, 0x43, 0x85, 0x8f,
-  0x42, 0x84, 0x8e, 0x41, 0x83, 0x8d, 0x40, 0x82, 0x8d, 0x3f, 0x82, 0x8b,
-  0x3d, 0x80, 0x8a, 0x3c, 0x7f, 0x89, 0x3b, 0x7e, 0x88, 0x3a, 0x7c, 0x87,
-  0x38, 0x7b, 0x85, 0x37, 0x7a, 0x84, 0x36, 0x79, 0x83, 0x34, 0x77, 0x81,
-  0x33, 0x76, 0x80, 0x31, 0x74, 0x7e, 0x31, 0x73, 0x7e, 0x30, 0x72, 0x7c,
-  0x2d, 0x71, 0x7a, 0x2c, 0x6f, 0x7a, 0x2b, 0x6e, 0x78, 0x29, 0x6c, 0x77,
-  0x28, 0x6b, 0x76, 0x27, 0x6a, 0x74, 0x26, 0x68, 0x72, 0x25, 0x67, 0x71,
-  0x24, 0x66, 0x71, 0x22, 0x65, 0x6f, 0x21, 0x63, 0x6f, 0x20, 0x62, 0x6d,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x00, 0x22, 0x27,
+  0x12, 0x35, 0x3a, 0xcc, 0xd7, 0xd9, 0xff, 0xff, 0xff, 0xd6, 0xe5, 0xe7,
+  0x51, 0x8f, 0x99, 0x43, 0x86, 0x90, 0x41, 0x84, 0x8e, 0x41, 0x84, 0x8e,
+  0x40, 0x83, 0x8d, 0x3f, 0x82, 0x8c, 0x3e, 0x81, 0x8c, 0x3d, 0x80, 0x8a,
+  0x3c, 0x7f, 0x8a, 0x3c, 0x7e, 0x88, 0x39, 0x7c, 0x86, 0x38, 0x7b, 0x86,
+  0x37, 0x7a, 0x84, 0x36, 0x7a, 0x84, 0x34, 0x78, 0x82, 0x33, 0x76, 0x80,
+  0x32, 0x75, 0x80, 0x31, 0x73, 0x7e, 0x30, 0x73, 0x7d, 0x2e, 0x71, 0x7b,
+  0x2c, 0x70, 0x7a, 0x2b, 0x6e, 0x79, 0x29, 0x6d, 0x77, 0x28, 0x6c, 0x77,
+  0x27, 0x6a, 0x75, 0x26, 0x69, 0x74, 0x26, 0x68, 0x72, 0x24, 0x67, 0x71,
+  0x23, 0x65, 0x70, 0x21, 0x64, 0x6f, 0x20, 0x63, 0x6e, 0x1f, 0x61, 0x6d,
+  0x1e, 0x61, 0x6b, 0x1d, 0x5f, 0x69, 0x1c, 0x5e, 0x69, 0x1b, 0x5d, 0x67,
+  0x1a, 0x5b, 0x66, 0x19, 0x5b, 0x65, 0x18, 0x59, 0x64, 0x18, 0x59, 0x62,
+  0x18, 0x58, 0x61, 0x17, 0x56, 0x61, 0x16, 0x54, 0x5f, 0x16, 0x54, 0x5e,
+  0x15, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x50, 0x5a,
+  0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
+  0x12, 0x4c, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
+  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
+  0x0e, 0x45, 0x4e, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
+  0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x00, 0x1f, 0x23, 0x26, 0x49, 0x4e, 0xf1, 0xf5, 0xf5, 0xff, 0xff, 0xff,
+  0xc7, 0xdb, 0xde, 0x4a, 0x8a, 0x95, 0x45, 0x86, 0x90, 0x45, 0x86, 0x90,
+  0x44, 0x85, 0x8f, 0x42, 0x83, 0x8e, 0x41, 0x83, 0x8d, 0x40, 0x82, 0x8c,
+  0x3f, 0x81, 0x8b, 0x3d, 0x80, 0x8a, 0x3c, 0x7e, 0x88, 0x3b, 0x7d, 0x88,
+  0x3a, 0x7c, 0x86, 0x38, 0x7b, 0x85, 0x37, 0x79, 0x84, 0x36, 0x78, 0x82,
+  0x34, 0x77, 0x81, 0x33, 0x75, 0x80, 0x31, 0x74, 0x7e, 0x31, 0x72, 0x7d,
+  0x2e, 0x71, 0x7b, 0x2d, 0x70, 0x7a, 0x2b, 0x6e, 0x78, 0x2a, 0x6d, 0x78,
+  0x29, 0x6b, 0x76, 0x27, 0x6a, 0x74, 0x26, 0x69, 0x73, 0x26, 0x68, 0x72,
+  0x25, 0x66, 0x71, 0x22, 0x65, 0x6f, 0x21, 0x63, 0x6f, 0x20, 0x62, 0x6d,
   0x1f, 0x61, 0x6c, 0x1e, 0x60, 0x6a, 0x1d, 0x5f, 0x69, 0x1c, 0x5d, 0x68,
-  0x1b, 0x5c, 0x66, 0x19, 0x5b, 0x65, 0x18, 0x59, 0x64, 0x18, 0x59, 0x63,
+  0x1b, 0x5c, 0x66, 0x19, 0x5b, 0x65, 0x19, 0x5a, 0x65, 0x18, 0x59, 0x63,
   0x18, 0x58, 0x61, 0x17, 0x56, 0x61, 0x17, 0x55, 0x60, 0x16, 0x54, 0x5e,
-  0x16, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x50, 0x5a,
+  0x16, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
   0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
   0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
@@ -5243,135 +5243,7 @@
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
   0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x28, 0x2d, 0x2b, 0x4f, 0x55, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5e, 0x6a, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x00, 0x1f, 0x25,
-  0x32, 0x55, 0x5a, 0xfa, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xaa, 0xc8, 0xcd,
-  0x48, 0x8a, 0x94, 0x47, 0x89, 0x93, 0x47, 0x88, 0x92, 0x47, 0x87, 0x91,
-  0x46, 0x87, 0x90, 0x44, 0x85, 0x8f, 0x43, 0x84, 0x8e, 0x42, 0x83, 0x8d,
-  0x41, 0x82, 0x8d, 0x3f, 0x81, 0x8b, 0x3d, 0x7f, 0x89, 0x3d, 0x7e, 0x89,
-  0x3b, 0x7d, 0x87, 0x3a, 0x7c, 0x86, 0x38, 0x7a, 0x84, 0x37, 0x79, 0x83,
-  0x36, 0x78, 0x82, 0x34, 0x76, 0x80, 0x32, 0x75, 0x7f, 0x31, 0x73, 0x7e,
-  0x2f, 0x72, 0x7c, 0x2e, 0x70, 0x7b, 0x2d, 0x70, 0x79, 0x2b, 0x6e, 0x78,
-  0x2a, 0x6c, 0x77, 0x28, 0x6b, 0x75, 0x27, 0x69, 0x73, 0x26, 0x69, 0x73,
-  0x25, 0x66, 0x71, 0x23, 0x66, 0x70, 0x22, 0x64, 0x6f, 0x21, 0x62, 0x6e,
-  0x20, 0x62, 0x6c, 0x1f, 0x60, 0x6b, 0x1e, 0x60, 0x6a, 0x1d, 0x5e, 0x68,
-  0x1c, 0x5c, 0x67, 0x1a, 0x5c, 0x65, 0x19, 0x5a, 0x65, 0x18, 0x59, 0x63,
-  0x18, 0x58, 0x61, 0x18, 0x57, 0x61, 0x17, 0x55, 0x60, 0x17, 0x55, 0x5f,
-  0x16, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
-  0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58, 0x12, 0x4c, 0x56,
-  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
-  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
-  0x0f, 0x46, 0x4f, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
-  0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x2f, 0x1b, 0x42, 0x48, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x02, 0x26, 0x2c,
-  0x00, 0x1f, 0x24, 0x56, 0x73, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0x9d, 0xc0, 0xc6, 0x4b, 0x8b, 0x95, 0x4a, 0x8a, 0x94, 0x49, 0x89, 0x93,
-  0x48, 0x88, 0x92, 0x47, 0x87, 0x91, 0x47, 0x86, 0x91, 0x45, 0x85, 0x8f,
-  0x44, 0x84, 0x8e, 0x43, 0x83, 0x8d, 0x41, 0x82, 0x8b, 0x3f, 0x80, 0x8a,
-  0x3e, 0x7f, 0x89, 0x3d, 0x7e, 0x88, 0x3b, 0x7c, 0x86, 0x3a, 0x7a, 0x84,
-  0x38, 0x79, 0x83, 0x37, 0x78, 0x82, 0x35, 0x76, 0x81, 0x33, 0x74, 0x7f,
-  0x32, 0x74, 0x7d, 0x30, 0x72, 0x7c, 0x2f, 0x71, 0x7b, 0x2d, 0x6f, 0x79,
-  0x2c, 0x6d, 0x78, 0x2a, 0x6c, 0x76, 0x29, 0x6a, 0x74, 0x27, 0x69, 0x73,
-  0x26, 0x68, 0x73, 0x25, 0x67, 0x71, 0x23, 0x65, 0x70, 0x22, 0x63, 0x6e,
-  0x21, 0x62, 0x6d, 0x20, 0x61, 0x6b, 0x1f, 0x60, 0x6b, 0x1e, 0x5f, 0x69,
-  0x1d, 0x5d, 0x67, 0x1b, 0x5c, 0x66, 0x1a, 0x5b, 0x65, 0x19, 0x5a, 0x64,
-  0x18, 0x58, 0x62, 0x18, 0x57, 0x61, 0x18, 0x56, 0x60, 0x17, 0x55, 0x5f,
-  0x16, 0x53, 0x5d, 0x16, 0x53, 0x5d, 0x15, 0x52, 0x5c, 0x14, 0x51, 0x5b,
-  0x14, 0x50, 0x5a, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58, 0x12, 0x4c, 0x56,
-  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x10, 0x4a, 0x53,
-  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
-  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
-  0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x45, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -5412,21 +5284,85 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x01, 0x24, 0x29, 0x01, 0x22, 0x27, 0x89, 0x9f, 0xa3, 0xff, 0xff, 0xff,
-  0xfe, 0xff, 0xff, 0x8b, 0xb4, 0xba, 0x4e, 0x8c, 0x96, 0x4d, 0x8b, 0x95,
-  0x4c, 0x8b, 0x94, 0x4b, 0x89, 0x93, 0x49, 0x88, 0x92, 0x48, 0x88, 0x91,
-  0x47, 0x86, 0x90, 0x46, 0x85, 0x8f, 0x44, 0x84, 0x8d, 0x42, 0x82, 0x8c,
-  0x40, 0x80, 0x8a, 0x3f, 0x80, 0x8a, 0x3d, 0x7e, 0x88, 0x3c, 0x7c, 0x86,
-  0x3b, 0x7b, 0x85, 0x39, 0x79, 0x83, 0x37, 0x78, 0x82, 0x36, 0x76, 0x80,
-  0x33, 0x75, 0x7e, 0x32, 0x73, 0x7d, 0x31, 0x72, 0x7c, 0x2f, 0x70, 0x7b,
-  0x2e, 0x6f, 0x79, 0x2c, 0x6d, 0x77, 0x2a, 0x6b, 0x75, 0x29, 0x6a, 0x74,
-  0x27, 0x68, 0x73, 0x26, 0x68, 0x72, 0x25, 0x66, 0x71, 0x23, 0x64, 0x6f,
-  0x22, 0x63, 0x6d, 0x21, 0x62, 0x6c, 0x20, 0x61, 0x6b, 0x1f, 0x5f, 0x6a,
-  0x1e, 0x5e, 0x68, 0x1b, 0x5c, 0x66, 0x1a, 0x5b, 0x65, 0x1a, 0x5b, 0x64,
-  0x19, 0x59, 0x63, 0x18, 0x57, 0x62, 0x18, 0x56, 0x61, 0x17, 0x55, 0x5f,
-  0x17, 0x54, 0x5e, 0x17, 0x54, 0x5e, 0x15, 0x52, 0x5c, 0x14, 0x51, 0x5b,
+  0x02, 0x25, 0x2a, 0x00, 0x1d, 0x22, 0x4d, 0x6c, 0x71, 0xfe, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xb1, 0xcd, 0xd1, 0x48, 0x88, 0x93, 0x47, 0x88, 0x92,
+  0x47, 0x87, 0x91, 0x46, 0x86, 0x90, 0x45, 0x85, 0x90, 0x43, 0x84, 0x8e,
+  0x42, 0x83, 0x8d, 0x41, 0x82, 0x8c, 0x3e, 0x80, 0x8a, 0x3d, 0x7f, 0x89,
+  0x3d, 0x7e, 0x88, 0x3b, 0x7d, 0x87, 0x3a, 0x7b, 0x85, 0x38, 0x79, 0x83,
+  0x37, 0x79, 0x83, 0x35, 0x76, 0x81, 0x34, 0x76, 0x80, 0x32, 0x74, 0x7e,
+  0x30, 0x72, 0x7c, 0x2f, 0x71, 0x7c, 0x2d, 0x70, 0x79, 0x2c, 0x6e, 0x79,
+  0x2a, 0x6c, 0x77, 0x29, 0x6b, 0x75, 0x28, 0x6a, 0x74, 0x26, 0x69, 0x73,
+  0x26, 0x67, 0x72, 0x24, 0x66, 0x70, 0x23, 0x65, 0x70, 0x21, 0x62, 0x6e,
+  0x20, 0x62, 0x6c, 0x1f, 0x60, 0x6b, 0x1e, 0x60, 0x6a, 0x1d, 0x5e, 0x68,
+  0x1c, 0x5c, 0x67, 0x1a, 0x5c, 0x65, 0x19, 0x5a, 0x65, 0x18, 0x59, 0x63,
+  0x18, 0x58, 0x62, 0x18, 0x57, 0x61, 0x17, 0x55, 0x60, 0x17, 0x55, 0x5f,
+  0x16, 0x53, 0x5d, 0x16, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
+  0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58, 0x12, 0x4c, 0x56,
+  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x10, 0x4a, 0x53,
+  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
+  0x0f, 0x46, 0x4f, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
+  0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x01, 0x23, 0x28, 0x00, 0x20, 0x25, 0x89, 0xa0, 0xa4,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xbc, 0xc2, 0x4b, 0x8a, 0x94,
+  0x4a, 0x8a, 0x93, 0x48, 0x88, 0x92, 0x47, 0x87, 0x91, 0x47, 0x86, 0x90,
+  0x45, 0x84, 0x8f, 0x44, 0x84, 0x8d, 0x42, 0x82, 0x8c, 0x41, 0x81, 0x8b,
+  0x3f, 0x80, 0x8a, 0x3d, 0x7f, 0x88, 0x3d, 0x7d, 0x87, 0x3b, 0x7b, 0x85,
+  0x39, 0x7a, 0x84, 0x38, 0x78, 0x82, 0x36, 0x77, 0x81, 0x34, 0x75, 0x7f,
+  0x32, 0x74, 0x7e, 0x31, 0x72, 0x7d, 0x30, 0x72, 0x7b, 0x2e, 0x6f, 0x7a,
+  0x2c, 0x6d, 0x78, 0x2b, 0x6d, 0x76, 0x29, 0x6a, 0x74, 0x28, 0x6a, 0x74,
+  0x27, 0x68, 0x73, 0x25, 0x67, 0x71, 0x24, 0x65, 0x70, 0x23, 0x64, 0x6f,
+  0x21, 0x62, 0x6d, 0x20, 0x61, 0x6b, 0x1f, 0x60, 0x6b, 0x1e, 0x5f, 0x69,
+  0x1d, 0x5d, 0x67, 0x1b, 0x5c, 0x66, 0x1a, 0x5b, 0x65, 0x19, 0x5a, 0x64,
+  0x18, 0x58, 0x62, 0x18, 0x57, 0x62, 0x18, 0x56, 0x60, 0x17, 0x55, 0x5f,
+  0x17, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
   0x14, 0x50, 0x5a, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58, 0x13, 0x4d, 0x57,
-  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
+  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x10, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
   0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
@@ -5476,21 +5412,21 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2b, 0x00, 0x20, 0x25, 0x0d, 0x2d, 0x33, 0xc3, 0xd0, 0xd2,
-  0xff, 0xff, 0xff, 0xf3, 0xf8, 0xf8, 0x76, 0xa5, 0xad, 0x51, 0x8e, 0x97,
-  0x50, 0x8d, 0x96, 0x4e, 0x8b, 0x95, 0x4d, 0x8b, 0x94, 0x4c, 0x8a, 0x93,
-  0x4a, 0x88, 0x92, 0x49, 0x87, 0x91, 0x47, 0x85, 0x8f, 0x45, 0x83, 0x8e,
-  0x44, 0x83, 0x8c, 0x42, 0x82, 0x8b, 0x40, 0x80, 0x89, 0x3f, 0x7e, 0x88,
-  0x3d, 0x7c, 0x86, 0x3c, 0x7b, 0x85, 0x3a, 0x7a, 0x84, 0x38, 0x77, 0x82,
-  0x35, 0x76, 0x80, 0x34, 0x75, 0x7f, 0x32, 0x73, 0x7d, 0x31, 0x71, 0x7c,
-  0x30, 0x70, 0x7a, 0x2e, 0x6f, 0x78, 0x2c, 0x6c, 0x76, 0x2b, 0x6c, 0x76,
-  0x29, 0x6a, 0x74, 0x27, 0x69, 0x73, 0x26, 0x67, 0x72, 0x25, 0x65, 0x70,
-  0x23, 0x64, 0x6e, 0x22, 0x62, 0x6c, 0x21, 0x62, 0x6c, 0x20, 0x60, 0x6a,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x00, 0x1e, 0x23, 0x0e, 0x2e, 0x33,
+  0xca, 0xd6, 0xd7, 0xff, 0xff, 0xff, 0xf9, 0xfb, 0xfb, 0x7a, 0xa9, 0xb0,
+  0x4e, 0x8c, 0x95, 0x4c, 0x8a, 0x94, 0x4b, 0x89, 0x93, 0x4a, 0x89, 0x92,
+  0x48, 0x87, 0x91, 0x47, 0x86, 0x90, 0x45, 0x84, 0x8e, 0x43, 0x82, 0x8d,
+  0x42, 0x82, 0x8b, 0x41, 0x81, 0x8b, 0x3e, 0x7e, 0x88, 0x3d, 0x7d, 0x87,
+  0x3c, 0x7c, 0x86, 0x3a, 0x7a, 0x84, 0x39, 0x79, 0x83, 0x37, 0x77, 0x81,
+  0x34, 0x76, 0x7f, 0x32, 0x73, 0x7e, 0x32, 0x73, 0x7c, 0x30, 0x71, 0x7b,
+  0x2e, 0x6f, 0x79, 0x2d, 0x6e, 0x78, 0x2b, 0x6c, 0x76, 0x2a, 0x6b, 0x75,
+  0x28, 0x69, 0x74, 0x26, 0x68, 0x72, 0x25, 0x66, 0x71, 0x24, 0x64, 0x70,
+  0x23, 0x64, 0x6e, 0x21, 0x62, 0x6c, 0x20, 0x61, 0x6b, 0x1f, 0x5f, 0x6a,
   0x1e, 0x5e, 0x68, 0x1c, 0x5d, 0x67, 0x1b, 0x5b, 0x66, 0x1a, 0x5b, 0x64,
-  0x19, 0x59, 0x63, 0x19, 0x58, 0x63, 0x18, 0x56, 0x61, 0x18, 0x56, 0x60,
-  0x17, 0x54, 0x5e, 0x17, 0x54, 0x5e, 0x15, 0x52, 0x5c, 0x15, 0x51, 0x5b,
+  0x19, 0x59, 0x63, 0x19, 0x58, 0x63, 0x18, 0x56, 0x60, 0x18, 0x56, 0x60,
+  0x17, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x15, 0x52, 0x5c, 0x15, 0x51, 0x5b,
   0x14, 0x50, 0x5a, 0x14, 0x50, 0x59, 0x13, 0x4e, 0x58, 0x13, 0x4d, 0x57,
-  0x13, 0x4d, 0x56, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
+  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0e, 0x43, 0x4b,
   0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
@@ -5540,20 +5476,20 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x00, 0x1c, 0x21, 0x27, 0x48, 0x4e,
-  0xf9, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xe2, 0xec, 0xee, 0x64, 0x9a, 0xa4,
-  0x53, 0x90, 0x98, 0x52, 0x8e, 0x97, 0x51, 0x8d, 0x97, 0x50, 0x8c, 0x95,
-  0x4e, 0x8a, 0x94, 0x4c, 0x89, 0x92, 0x4a, 0x88, 0x91, 0x49, 0x86, 0x90,
-  0x47, 0x85, 0x8e, 0x45, 0x83, 0x8d, 0x43, 0x81, 0x8b, 0x41, 0x7f, 0x89,
-  0x3f, 0x7e, 0x88, 0x3d, 0x7c, 0x86, 0x3d, 0x7b, 0x85, 0x3b, 0x79, 0x83,
-  0x38, 0x78, 0x81, 0x36, 0x76, 0x80, 0x34, 0x75, 0x7e, 0x32, 0x73, 0x7d,
-  0x32, 0x71, 0x7c, 0x30, 0x70, 0x79, 0x2e, 0x6e, 0x77, 0x2c, 0x6c, 0x76,
-  0x2b, 0x6b, 0x76, 0x28, 0x6a, 0x73, 0x27, 0x68, 0x73, 0x26, 0x66, 0x71,
-  0x25, 0x65, 0x6f, 0x23, 0x63, 0x6d, 0x22, 0x62, 0x6c, 0x21, 0x61, 0x6b,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x00, 0x1b, 0x1f,
+  0x31, 0x51, 0x56, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xe5, 0xee, 0xef,
+  0x64, 0x9a, 0xa2, 0x50, 0x8c, 0x96, 0x4f, 0x8c, 0x96, 0x4e, 0x8b, 0x94,
+  0x4c, 0x89, 0x93, 0x4b, 0x89, 0x92, 0x49, 0x87, 0x90, 0x47, 0x85, 0x8f,
+  0x45, 0x83, 0x8d, 0x43, 0x82, 0x8c, 0x41, 0x80, 0x8a, 0x40, 0x7f, 0x88,
+  0x3e, 0x7e, 0x87, 0x3d, 0x7b, 0x85, 0x3b, 0x7a, 0x84, 0x39, 0x78, 0x82,
+  0x36, 0x77, 0x80, 0x35, 0x75, 0x80, 0x33, 0x74, 0x7e, 0x32, 0x72, 0x7c,
+  0x31, 0x70, 0x7b, 0x2f, 0x6f, 0x79, 0x2d, 0x6d, 0x77, 0x2b, 0x6c, 0x76,
+  0x2a, 0x6a, 0x75, 0x27, 0x69, 0x73, 0x26, 0x67, 0x72, 0x25, 0x65, 0x70,
+  0x24, 0x64, 0x6f, 0x23, 0x63, 0x6d, 0x21, 0x62, 0x6c, 0x20, 0x60, 0x6a,
   0x1f, 0x5e, 0x69, 0x1d, 0x5e, 0x67, 0x1c, 0x5c, 0x67, 0x1b, 0x5b, 0x65,
   0x1a, 0x5a, 0x63, 0x19, 0x58, 0x63, 0x18, 0x56, 0x61, 0x18, 0x56, 0x60,
   0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x15, 0x51, 0x5b,
-  0x15, 0x50, 0x5a, 0x14, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x13, 0x4d, 0x57,
+  0x14, 0x50, 0x5a, 0x14, 0x50, 0x59, 0x13, 0x4e, 0x58, 0x13, 0x4d, 0x57,
   0x13, 0x4d, 0x56, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
   0x11, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0e, 0x43, 0x4b,
@@ -5604,22 +5540,22 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x22, 0x27, 0x00, 0x1b, 0x20,
-  0x5e, 0x7a, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xdb, 0xde,
-  0x57, 0x92, 0x9b, 0x55, 0x90, 0x99, 0x54, 0x8f, 0x99, 0x53, 0x8f, 0x98,
-  0x52, 0x8d, 0x96, 0x50, 0x8c, 0x95, 0x4d, 0x8a, 0x93, 0x4c, 0x88, 0x92,
-  0x4a, 0x87, 0x90, 0x49, 0x86, 0x8f, 0x47, 0x84, 0x8d, 0x45, 0x82, 0x8b,
-  0x42, 0x80, 0x8a, 0x40, 0x7e, 0x88, 0x3e, 0x7d, 0x87, 0x3d, 0x7b, 0x85,
-  0x3b, 0x7a, 0x83, 0x39, 0x78, 0x82, 0x37, 0x77, 0x80, 0x35, 0x75, 0x7f,
-  0x33, 0x72, 0x7d, 0x32, 0x71, 0x7b, 0x30, 0x6f, 0x79, 0x2e, 0x6e, 0x77,
-  0x2d, 0x6c, 0x77, 0x2a, 0x6b, 0x75, 0x28, 0x69, 0x73, 0x27, 0x67, 0x72,
-  0x26, 0x66, 0x70, 0x25, 0x64, 0x6e, 0x23, 0x63, 0x6d, 0x22, 0x61, 0x6c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x20, 0x25,
+  0x00, 0x1b, 0x1f, 0x77, 0x90, 0x93, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xc5, 0xd9, 0xdc, 0x53, 0x8f, 0x98, 0x52, 0x8e, 0x98, 0x52, 0x8e, 0x96,
+  0x50, 0x8c, 0x95, 0x4e, 0x8a, 0x94, 0x4b, 0x88, 0x92, 0x4a, 0x87, 0x91,
+  0x49, 0x86, 0x8f, 0x47, 0x85, 0x8e, 0x45, 0x83, 0x8c, 0x43, 0x81, 0x8a,
+  0x41, 0x7f, 0x89, 0x3f, 0x7d, 0x87, 0x3d, 0x7c, 0x86, 0x3c, 0x7a, 0x84,
+  0x39, 0x79, 0x82, 0x37, 0x77, 0x81, 0x35, 0x75, 0x7f, 0x33, 0x73, 0x7e,
+  0x32, 0x72, 0x7c, 0x31, 0x70, 0x7a, 0x2f, 0x6e, 0x78, 0x2d, 0x6d, 0x77,
+  0x2c, 0x6b, 0x76, 0x29, 0x6a, 0x74, 0x27, 0x68, 0x73, 0x26, 0x66, 0x71,
+  0x25, 0x65, 0x6f, 0x24, 0x64, 0x6e, 0x23, 0x63, 0x6d, 0x21, 0x61, 0x6b,
   0x20, 0x5f, 0x69, 0x1e, 0x5e, 0x68, 0x1d, 0x5d, 0x67, 0x1c, 0x5c, 0x66,
-  0x1b, 0x5a, 0x64, 0x1a, 0x59, 0x63, 0x19, 0x57, 0x62, 0x19, 0x57, 0x61,
-  0x18, 0x55, 0x5f, 0x18, 0x55, 0x5f, 0x16, 0x53, 0x5d, 0x16, 0x52, 0x5c,
+  0x1a, 0x5a, 0x63, 0x1a, 0x59, 0x63, 0x19, 0x57, 0x62, 0x18, 0x56, 0x60,
+  0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x15, 0x51, 0x5b,
   0x15, 0x50, 0x5a, 0x14, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x13, 0x4d, 0x57,
   0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
-  0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
+  0x11, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
@@ -5668,20 +5604,84 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x00, 0x1f, 0x24,
-  0x05, 0x24, 0x29, 0xae, 0xbe, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xa4, 0xc4, 0xc9, 0x5a, 0x93, 0x9c, 0x58, 0x92, 0x9b, 0x57, 0x91, 0x9a,
-  0x55, 0x8f, 0x99, 0x52, 0x8d, 0x96, 0x50, 0x8c, 0x94, 0x4f, 0x8a, 0x94,
-  0x4d, 0x89, 0x92, 0x4b, 0x88, 0x91, 0x49, 0x86, 0x8f, 0x48, 0x84, 0x8d,
-  0x46, 0x82, 0x8c, 0x43, 0x80, 0x89, 0x41, 0x7f, 0x88, 0x3f, 0x7c, 0x86,
-  0x3d, 0x7b, 0x84, 0x3b, 0x79, 0x83, 0x39, 0x78, 0x81, 0x37, 0x76, 0x80,
-  0x35, 0x74, 0x7e, 0x33, 0x72, 0x7c, 0x32, 0x70, 0x7a, 0x30, 0x6f, 0x79,
-  0x2e, 0x6d, 0x77, 0x2c, 0x6c, 0x76, 0x2a, 0x6a, 0x75, 0x28, 0x68, 0x73,
-  0x26, 0x66, 0x70, 0x26, 0x65, 0x6f, 0x24, 0x64, 0x6e, 0x23, 0x62, 0x6c,
-  0x22, 0x60, 0x6b, 0x1f, 0x5f, 0x68, 0x1e, 0x5d, 0x68, 0x1d, 0x5d, 0x66,
-  0x1c, 0x5b, 0x65, 0x1b, 0x59, 0x64, 0x1a, 0x58, 0x62, 0x19, 0x57, 0x61,
-  0x18, 0x55, 0x5f, 0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x52, 0x5c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x00, 0x1c, 0x20, 0x0d, 0x2b, 0x30, 0xcd, 0xd7, 0xd8, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x9b, 0xbd, 0xc3, 0x56, 0x91, 0x9a, 0x55, 0x90, 0x99,
+  0x53, 0x8e, 0x98, 0x52, 0x8d, 0x96, 0x4f, 0x8b, 0x94, 0x4d, 0x89, 0x93,
+  0x4b, 0x88, 0x91, 0x49, 0x86, 0x90, 0x48, 0x84, 0x8e, 0x46, 0x82, 0x8c,
+  0x44, 0x81, 0x8b, 0x42, 0x7f, 0x89, 0x40, 0x7e, 0x88, 0x3e, 0x7c, 0x86,
+  0x3c, 0x7b, 0x84, 0x3a, 0x79, 0x83, 0x38, 0x77, 0x81, 0x36, 0x75, 0x7f,
+  0x34, 0x73, 0x7d, 0x32, 0x72, 0x7b, 0x31, 0x70, 0x79, 0x2f, 0x6e, 0x78,
+  0x2d, 0x6c, 0x77, 0x2b, 0x6b, 0x75, 0x29, 0x69, 0x74, 0x27, 0x67, 0x72,
+  0x26, 0x66, 0x70, 0x25, 0x64, 0x6e, 0x24, 0x64, 0x6e, 0x22, 0x61, 0x6c,
+  0x21, 0x60, 0x6a, 0x1f, 0x5f, 0x68, 0x1e, 0x5d, 0x68, 0x1c, 0x5c, 0x66,
+  0x1b, 0x5a, 0x64, 0x1a, 0x59, 0x63, 0x19, 0x57, 0x62, 0x18, 0x56, 0x60,
+  0x18, 0x55, 0x5f, 0x18, 0x55, 0x5f, 0x16, 0x53, 0x5d, 0x15, 0x51, 0x5b,
   0x15, 0x50, 0x5a, 0x15, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x14, 0x4e, 0x58,
+  0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
+  0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
+  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
+  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x00, 0x18, 0x1c, 0x3b, 0x58, 0x5e, 0xfe, 0xfe, 0xfe,
+  0xff, 0xff, 0xff, 0xf2, 0xf6, 0xf7, 0x74, 0xa4, 0xac, 0x58, 0x92, 0x9a,
+  0x57, 0x90, 0x9a, 0x55, 0x8f, 0x98, 0x53, 0x8d, 0x96, 0x50, 0x8b, 0x94,
+  0x4e, 0x8a, 0x93, 0x4d, 0x89, 0x92, 0x4a, 0x86, 0x90, 0x49, 0x84, 0x8e,
+  0x47, 0x83, 0x8c, 0x45, 0x81, 0x8b, 0x43, 0x80, 0x89, 0x41, 0x7e, 0x87,
+  0x3e, 0x7c, 0x85, 0x3c, 0x7a, 0x84, 0x3a, 0x79, 0x82, 0x38, 0x76, 0x81,
+  0x36, 0x74, 0x7f, 0x34, 0x73, 0x7c, 0x32, 0x71, 0x7a, 0x31, 0x70, 0x79,
+  0x2f, 0x6d, 0x78, 0x2c, 0x6c, 0x76, 0x2b, 0x6b, 0x75, 0x29, 0x68, 0x73,
+  0x27, 0x67, 0x71, 0x26, 0x65, 0x6f, 0x25, 0x64, 0x6e, 0x24, 0x63, 0x6d,
+  0x22, 0x60, 0x6b, 0x20, 0x60, 0x69, 0x1e, 0x5d, 0x68, 0x1d, 0x5d, 0x66,
+  0x1c, 0x5b, 0x65, 0x1b, 0x59, 0x64, 0x1a, 0x58, 0x62, 0x19, 0x57, 0x61,
+  0x19, 0x56, 0x60, 0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x52, 0x5c,
+  0x16, 0x51, 0x5b, 0x15, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x14, 0x4e, 0x58,
   0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x12, 0x4c, 0x55, 0x11, 0x4a, 0x53,
   0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
@@ -5733,18 +5733,18 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x00, 0x1a, 0x1e, 0x22, 0x42, 0x47, 0xf9, 0xfb, 0xfb, 0xff, 0xff, 0xff,
-  0xf7, 0xfa, 0xfa, 0x81, 0xad, 0xb4, 0x5c, 0x94, 0x9d, 0x5b, 0x94, 0x9c,
-  0x59, 0x92, 0x9b, 0x57, 0x90, 0x99, 0x55, 0x8f, 0x97, 0x52, 0x8c, 0x96,
-  0x50, 0x8b, 0x94, 0x4f, 0x8a, 0x93, 0x4c, 0x88, 0x91, 0x4a, 0x86, 0x8f,
-  0x49, 0x84, 0x8e, 0x47, 0x82, 0x8c, 0x44, 0x80, 0x8a, 0x42, 0x7e, 0x88,
-  0x3f, 0x7d, 0x86, 0x3e, 0x7b, 0x85, 0x3b, 0x79, 0x82, 0x39, 0x77, 0x81,
-  0x37, 0x75, 0x7f, 0x35, 0x74, 0x7d, 0x33, 0x72, 0x7b, 0x32, 0x70, 0x7a,
-  0x30, 0x6e, 0x79, 0x2d, 0x6d, 0x77, 0x2b, 0x6b, 0x75, 0x2a, 0x69, 0x74,
-  0x28, 0x68, 0x72, 0x26, 0x65, 0x70, 0x26, 0x65, 0x6f, 0x24, 0x63, 0x6d,
-  0x23, 0x61, 0x6b, 0x20, 0x60, 0x69, 0x1f, 0x5e, 0x68, 0x1e, 0x5d, 0x67,
-  0x1d, 0x5c, 0x65, 0x1c, 0x5a, 0x65, 0x1a, 0x58, 0x62, 0x19, 0x57, 0x61,
-  0x18, 0x55, 0x5f, 0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x52, 0x5c,
+  0x02, 0x20, 0x24, 0x01, 0x1d, 0x21, 0x02, 0x1c, 0x21, 0x98, 0xab, 0xae,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xdf, 0xe2, 0x5d, 0x95, 0x9d,
+  0x5b, 0x93, 0x9c, 0x59, 0x92, 0x9a, 0x56, 0x90, 0x98, 0x55, 0x8e, 0x97,
+  0x52, 0x8c, 0x95, 0x50, 0x8b, 0x94, 0x4e, 0x89, 0x92, 0x4c, 0x87, 0x90,
+  0x49, 0x85, 0x8e, 0x48, 0x83, 0x8c, 0x46, 0x82, 0x8b, 0x43, 0x7f, 0x89,
+  0x40, 0x7e, 0x87, 0x3e, 0x7c, 0x85, 0x3d, 0x7a, 0x83, 0x3a, 0x78, 0x82,
+  0x38, 0x76, 0x80, 0x36, 0x74, 0x7e, 0x34, 0x72, 0x7c, 0x32, 0x71, 0x7a,
+  0x31, 0x6f, 0x79, 0x2e, 0x6d, 0x77, 0x2c, 0x6b, 0x76, 0x2a, 0x69, 0x74,
+  0x29, 0x68, 0x72, 0x27, 0x66, 0x70, 0x26, 0x65, 0x6f, 0x25, 0x63, 0x6d,
+  0x23, 0x61, 0x6b, 0x21, 0x60, 0x6a, 0x1f, 0x5e, 0x68, 0x1e, 0x5d, 0x67,
+  0x1d, 0x5c, 0x65, 0x1c, 0x5a, 0x65, 0x1b, 0x59, 0x63, 0x1a, 0x58, 0x61,
+  0x19, 0x56, 0x60, 0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x17, 0x53, 0x5d,
   0x16, 0x51, 0x5b, 0x15, 0x50, 0x59, 0x15, 0x50, 0x59, 0x14, 0x4e, 0x58,
   0x14, 0x4e, 0x57, 0x12, 0x4c, 0x55, 0x12, 0x4c, 0x55, 0x11, 0x4a, 0x53,
   0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x10, 0x47, 0x4f,
@@ -5797,19 +5797,19 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x1f, 0x24, 0x00, 0x19, 0x1d, 0x6a, 0x83, 0x87, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xdd, 0xe9, 0xeb, 0x64, 0x9a, 0xa2, 0x5d, 0x95, 0x9e,
-  0x5c, 0x94, 0x9d, 0x5a, 0x92, 0x9b, 0x57, 0x90, 0x99, 0x55, 0x8e, 0x98,
-  0x55, 0x8e, 0x97, 0x52, 0x8c, 0x95, 0x4f, 0x89, 0x92, 0x4d, 0x87, 0x90,
-  0x4b, 0x86, 0x8f, 0x49, 0x84, 0x8d, 0x48, 0x83, 0x8c, 0x45, 0x80, 0x8a,
-  0x42, 0x7f, 0x88, 0x3f, 0x7c, 0x86, 0x3e, 0x7b, 0x84, 0x3c, 0x79, 0x83,
-  0x3a, 0x77, 0x81, 0x37, 0x75, 0x7e, 0x35, 0x73, 0x7c, 0x33, 0x72, 0x7b,
-  0x32, 0x6f, 0x7a, 0x2f, 0x6e, 0x78, 0x2d, 0x6c, 0x77, 0x2b, 0x6a, 0x74,
-  0x29, 0x68, 0x72, 0x28, 0x67, 0x71, 0x26, 0x65, 0x70, 0x25, 0x63, 0x6d,
-  0x24, 0x62, 0x6c, 0x21, 0x60, 0x6a, 0x20, 0x5f, 0x69, 0x1f, 0x5e, 0x67,
-  0x1e, 0x5c, 0x66, 0x1c, 0x5a, 0x65, 0x1b, 0x59, 0x63, 0x1a, 0x58, 0x61,
-  0x19, 0x56, 0x60, 0x19, 0x56, 0x60, 0x17, 0x54, 0x5e, 0x17, 0x53, 0x5d,
-  0x16, 0x51, 0x5b, 0x16, 0x51, 0x5a, 0x15, 0x50, 0x59, 0x14, 0x4e, 0x58,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x00, 0x17, 0x1b, 0x1f, 0x3d, 0x41,
+  0xfa, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xbd, 0xc2,
+  0x5d, 0x95, 0x9e, 0x5c, 0x94, 0x9c, 0x59, 0x92, 0x9a, 0x57, 0x90, 0x99,
+  0x55, 0x8e, 0x97, 0x53, 0x8d, 0x95, 0x51, 0x8b, 0x94, 0x4f, 0x89, 0x92,
+  0x4c, 0x87, 0x90, 0x4a, 0x85, 0x8e, 0x49, 0x84, 0x8d, 0x46, 0x81, 0x8a,
+  0x43, 0x80, 0x88, 0x41, 0x7e, 0x87, 0x3e, 0x7c, 0x85, 0x3d, 0x7a, 0x83,
+  0x3b, 0x77, 0x81, 0x39, 0x76, 0x7f, 0x36, 0x73, 0x7d, 0x34, 0x72, 0x7c,
+  0x32, 0x70, 0x7a, 0x30, 0x6f, 0x78, 0x2e, 0x6d, 0x77, 0x2c, 0x6a, 0x75,
+  0x2a, 0x69, 0x73, 0x28, 0x67, 0x71, 0x26, 0x65, 0x70, 0x26, 0x64, 0x6e,
+  0x24, 0x62, 0x6c, 0x22, 0x61, 0x6a, 0x20, 0x5f, 0x69, 0x1f, 0x5e, 0x67,
+  0x1e, 0x5c, 0x66, 0x1d, 0x5b, 0x65, 0x1c, 0x59, 0x64, 0x1a, 0x58, 0x61,
+  0x19, 0x56, 0x60, 0x18, 0x55, 0x5f, 0x17, 0x55, 0x5e, 0x17, 0x53, 0x5d,
+  0x16, 0x51, 0x5b, 0x16, 0x51, 0x5a, 0x15, 0x50, 0x59, 0x15, 0x4f, 0x58,
   0x14, 0x4e, 0x57, 0x12, 0x4c, 0x55, 0x12, 0x4c, 0x55, 0x12, 0x4b, 0x54,
   0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
@@ -5861,20 +5861,20 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x00, 0x1b, 0x1f, 0x0b, 0x28, 0x2c, 0xca, 0xd5, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb1, 0xcc, 0xd1, 0x61, 0x98, 0xa0,
-  0x5f, 0x96, 0x9f, 0x5d, 0x95, 0x9d, 0x5b, 0x93, 0x9b, 0x59, 0x91, 0x9a,
-  0x57, 0x90, 0x98, 0x55, 0x8e, 0x97, 0x53, 0x8c, 0x95, 0x51, 0x8a, 0x93,
-  0x4e, 0x88, 0x91, 0x4c, 0x86, 0x8f, 0x4a, 0x85, 0x8e, 0x48, 0x82, 0x8c,
-  0x45, 0x81, 0x8a, 0x42, 0x7e, 0x88, 0x40, 0x7d, 0x86, 0x3e, 0x7a, 0x84,
-  0x3c, 0x78, 0x82, 0x3a, 0x77, 0x80, 0x38, 0x75, 0x7e, 0x35, 0x73, 0x7c,
-  0x33, 0x71, 0x7b, 0x31, 0x6f, 0x79, 0x2f, 0x6d, 0x78, 0x2d, 0x6b, 0x76,
-  0x2b, 0x6a, 0x74, 0x29, 0x67, 0x71, 0x27, 0x66, 0x70, 0x26, 0x65, 0x6f,
-  0x25, 0x62, 0x6c, 0x22, 0x61, 0x6a, 0x21, 0x5f, 0x6a, 0x20, 0x5f, 0x68,
-  0x1f, 0x5d, 0x67, 0x1d, 0x5b, 0x65, 0x1c, 0x59, 0x64, 0x1b, 0x59, 0x62,
-  0x1a, 0x57, 0x60, 0x19, 0x56, 0x60, 0x17, 0x55, 0x5e, 0x17, 0x53, 0x5d,
-  0x17, 0x52, 0x5c, 0x16, 0x51, 0x5a, 0x15, 0x50, 0x59, 0x15, 0x4f, 0x58,
-  0x14, 0x4e, 0x57, 0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x12, 0x4b, 0x54,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1c, 0x21, 0x00, 0x16, 0x1a,
+  0x78, 0x8f, 0x92, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xea, 0xf1, 0xf2,
+  0x6f, 0xa0, 0xa8, 0x5f, 0x96, 0x9e, 0x5d, 0x94, 0x9c, 0x5a, 0x91, 0x9b,
+  0x58, 0x90, 0x99, 0x56, 0x8f, 0x98, 0x54, 0x8c, 0x95, 0x52, 0x8b, 0x93,
+  0x50, 0x89, 0x92, 0x4d, 0x87, 0x90, 0x4b, 0x85, 0x8f, 0x49, 0x83, 0x8c,
+  0x46, 0x82, 0x8a, 0x43, 0x7f, 0x88, 0x41, 0x7e, 0x86, 0x3f, 0x7b, 0x85,
+  0x3d, 0x79, 0x83, 0x3b, 0x77, 0x81, 0x39, 0x75, 0x7f, 0x36, 0x73, 0x7d,
+  0x34, 0x71, 0x7c, 0x32, 0x70, 0x7a, 0x30, 0x6e, 0x78, 0x2e, 0x6c, 0x76,
+  0x2c, 0x6a, 0x74, 0x2a, 0x68, 0x72, 0x28, 0x67, 0x71, 0x26, 0x65, 0x6f,
+  0x26, 0x63, 0x6d, 0x23, 0x62, 0x6b, 0x22, 0x60, 0x6a, 0x20, 0x5f, 0x68,
+  0x1f, 0x5d, 0x67, 0x25, 0x60, 0x6b, 0x30, 0x68, 0x72, 0x3b, 0x70, 0x78,
+  0x4b, 0x7b, 0x82, 0x56, 0x83, 0x8a, 0x58, 0x84, 0x8c, 0x51, 0x7f, 0x86,
+  0x4c, 0x79, 0x81, 0x3f, 0x70, 0x77, 0x31, 0x65, 0x6d, 0x26, 0x5b, 0x64,
+  0x18, 0x51, 0x5a, 0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x12, 0x4b, 0x54,
   0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
@@ -5925,21 +5925,21 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x00, 0x17, 0x1a, 0x3d, 0x5b, 0x5f,
-  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfb, 0xfb, 0x86, 0xaf, 0xb6,
-  0x63, 0x98, 0xa1, 0x61, 0x97, 0x9f, 0x5f, 0x95, 0x9d, 0x5d, 0x93, 0x9c,
-  0x5a, 0x91, 0x9a, 0x58, 0x90, 0x99, 0x55, 0x8e, 0x96, 0x54, 0x8c, 0x95,
-  0x51, 0x8a, 0x93, 0x4f, 0x88, 0x91, 0x4d, 0x87, 0x90, 0x4a, 0x84, 0x8d,
-  0x48, 0x83, 0x8b, 0x45, 0x80, 0x8a, 0x43, 0x7f, 0x88, 0x40, 0x7c, 0x86,
-  0x3e, 0x7a, 0x84, 0x3c, 0x78, 0x81, 0x3a, 0x76, 0x7f, 0x37, 0x74, 0x7d,
-  0x35, 0x72, 0x7c, 0x33, 0x71, 0x7a, 0x31, 0x6e, 0x79, 0x2f, 0x6c, 0x77,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x00, 0x17, 0x1b,
+  0x13, 0x2f, 0x34, 0xea, 0xef, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xb8, 0xd1, 0xd4, 0x63, 0x98, 0xa0, 0x60, 0x96, 0x9f, 0x5e, 0x94, 0x9d,
+  0x5c, 0x93, 0x9b, 0x59, 0x91, 0x99, 0x57, 0x8f, 0x98, 0x55, 0x8d, 0x96,
+  0x53, 0x8b, 0x94, 0x50, 0x89, 0x91, 0x4e, 0x87, 0x90, 0x4b, 0x85, 0x8e,
+  0x49, 0x83, 0x8c, 0x46, 0x81, 0x8a, 0x44, 0x7f, 0x88, 0x41, 0x7d, 0x86,
+  0x3f, 0x7b, 0x84, 0x3d, 0x79, 0x82, 0x3b, 0x77, 0x80, 0x38, 0x75, 0x7e,
+  0x36, 0x73, 0x7d, 0x33, 0x71, 0x7b, 0x32, 0x6f, 0x7a, 0x2f, 0x6c, 0x77,
   0x2d, 0x6b, 0x75, 0x2b, 0x69, 0x73, 0x29, 0x67, 0x71, 0x27, 0x65, 0x6f,
-  0x26, 0x63, 0x6d, 0x24, 0x62, 0x6c, 0x22, 0x60, 0x6a, 0x21, 0x5f, 0x69,
-  0x1f, 0x5d, 0x67, 0x1e, 0x5b, 0x66, 0x1d, 0x5a, 0x64, 0x1c, 0x59, 0x63,
-  0x1a, 0x57, 0x60, 0x19, 0x56, 0x60, 0x17, 0x55, 0x5e, 0x17, 0x54, 0x5d,
-  0x17, 0x52, 0x5c, 0x16, 0x51, 0x5a, 0x16, 0x50, 0x5a, 0x15, 0x4f, 0x58,
-  0x14, 0x4e, 0x57, 0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x12, 0x4b, 0x54,
-  0x12, 0x4a, 0x53, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
+  0x26, 0x64, 0x6e, 0x35, 0x6e, 0x78, 0x60, 0x8d, 0x94, 0x91, 0xb0, 0xb5,
+  0xb8, 0xcc, 0xcf, 0xd4, 0xe0, 0xe2, 0xec, 0xf1, 0xf2, 0xfd, 0xfe, 0xfe,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfa, 0xfa, 0xe4, 0xeb, 0xec,
+  0xcb, 0xd8, 0xd9, 0xab, 0xbf, 0xc3, 0x7f, 0x9f, 0xa4, 0x49, 0x75, 0x7c,
+  0x20, 0x55, 0x5d, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
@@ -5989,149 +5989,21 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x01, 0x1b, 0x1f, 0x03, 0x1d, 0x21,
-  0xa6, 0xb6, 0xb9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe7,
-  0x68, 0x9b, 0xa3, 0x65, 0x9a, 0xa1, 0x62, 0x98, 0xa0, 0x60, 0x96, 0x9f,
-  0x5e, 0x94, 0x9c, 0x5b, 0x92, 0x9a, 0x59, 0x90, 0x99, 0x56, 0x8e, 0x96,
-  0x55, 0x8c, 0x95, 0x52, 0x8a, 0x93, 0x50, 0x89, 0x91, 0x4d, 0x86, 0x8f,
-  0x4b, 0x85, 0x8d, 0x48, 0x82, 0x8b, 0x45, 0x80, 0x89, 0x43, 0x7e, 0x88,
-  0x40, 0x7b, 0x85, 0x3e, 0x7a, 0x83, 0x3c, 0x77, 0x80, 0x3a, 0x76, 0x7f,
-  0x37, 0x73, 0x7d, 0x34, 0x72, 0x7b, 0x33, 0x70, 0x7a, 0x30, 0x6d, 0x77,
-  0x2e, 0x6c, 0x75, 0x2c, 0x69, 0x73, 0x2a, 0x68, 0x72, 0x28, 0x66, 0x70,
-  0x26, 0x64, 0x6e, 0x25, 0x63, 0x6c, 0x23, 0x61, 0x6b, 0x22, 0x60, 0x69,
-  0x20, 0x5e, 0x67, 0x1f, 0x5c, 0x67, 0x1e, 0x5b, 0x65, 0x21, 0x5d, 0x67,
-  0x28, 0x62, 0x6a, 0x2c, 0x64, 0x6c, 0x2b, 0x63, 0x6c, 0x2a, 0x62, 0x6a,
-  0x27, 0x5f, 0x68, 0x21, 0x59, 0x62, 0x1a, 0x53, 0x5d, 0x15, 0x4f, 0x58,
-  0x15, 0x4f, 0x57, 0x13, 0x4d, 0x56, 0x13, 0x4d, 0x56, 0x12, 0x4b, 0x54,
-  0x12, 0x4a, 0x53, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
-  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
-  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x00, 0x16, 0x19,
-  0x29, 0x47, 0x4c, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xa0, 0xc1, 0xc6, 0x69, 0x9c, 0xa4, 0x66, 0x9a, 0xa2, 0x63, 0x98, 0xa0,
-  0x61, 0x96, 0x9e, 0x5f, 0x95, 0x9d, 0x5c, 0x92, 0x9a, 0x5a, 0x90, 0x99,
-  0x57, 0x8e, 0x97, 0x55, 0x8c, 0x95, 0x53, 0x8a, 0x93, 0x50, 0x88, 0x91,
-  0x4d, 0x87, 0x8f, 0x4b, 0x84, 0x8d, 0x48, 0x82, 0x8b, 0x45, 0x7f, 0x89,
-  0x43, 0x7d, 0x87, 0x40, 0x7b, 0x84, 0x3e, 0x79, 0x82, 0x3c, 0x77, 0x80,
-  0x39, 0x75, 0x7f, 0x36, 0x73, 0x7d, 0x33, 0x70, 0x7b, 0x32, 0x6e, 0x79,
-  0x30, 0x6d, 0x77, 0x2e, 0x6b, 0x74, 0x2c, 0x69, 0x73, 0x2a, 0x67, 0x71,
-  0x27, 0x64, 0x6e, 0x26, 0x64, 0x6d, 0x31, 0x6a, 0x75, 0x52, 0x83, 0x8a,
-  0x7e, 0xa2, 0xa7, 0xa2, 0xbc, 0xc0, 0xbc, 0xce, 0xd1, 0xd0, 0xdd, 0xdf,
-  0xdf, 0xe7, 0xe9, 0xe9, 0xef, 0xf0, 0xec, 0xf1, 0xf2, 0xeb, 0xf0, 0xf1,
-  0xe6, 0xed, 0xee, 0xdb, 0xe4, 0xe5, 0xca, 0xd7, 0xd9, 0xb4, 0xc6, 0xca,
-  0x97, 0xb1, 0xb5, 0x6e, 0x91, 0x97, 0x3e, 0x6e, 0x75, 0x1d, 0x53, 0x5c,
-  0x12, 0x4a, 0x53, 0x12, 0x49, 0x52, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
-  0x10, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
-  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1a, 0x1e,
-  0x01, 0x18, 0x1c, 0x94, 0xa7, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xe8, 0xf0, 0xf1, 0x74, 0xa3, 0xab, 0x6a, 0x9d, 0xa4, 0x67, 0x9a, 0xa2,
-  0x65, 0x99, 0xa1, 0x62, 0x97, 0x9f, 0x60, 0x94, 0x9d, 0x5d, 0x92, 0x9a,
-  0x5b, 0x91, 0x99, 0x58, 0x8e, 0x97, 0x55, 0x8c, 0x95, 0x54, 0x8a, 0x93,
-  0x50, 0x88, 0x91, 0x4d, 0x86, 0x8f, 0x4b, 0x84, 0x8c, 0x48, 0x81, 0x8b,
-  0x45, 0x7f, 0x88, 0x43, 0x7d, 0x86, 0x40, 0x7b, 0x83, 0x3e, 0x79, 0x82,
-  0x3b, 0x76, 0x80, 0x38, 0x75, 0x7e, 0x35, 0x72, 0x7c, 0x33, 0x70, 0x7a,
-  0x32, 0x6e, 0x78, 0x2f, 0x6b, 0x75, 0x2d, 0x6a, 0x74, 0x40, 0x77, 0x80,
-  0x7b, 0xa1, 0xa7, 0xb6, 0xcb, 0xce, 0xe6, 0xed, 0xee, 0xff, 0xff, 0xff,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x00, 0x14, 0x18, 0x69, 0x81, 0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xf7, 0xfa, 0xfa, 0x82, 0xad, 0xb3, 0x64, 0x99, 0xa1, 0x61, 0x96, 0x9f,
+  0x60, 0x95, 0x9d, 0x5d, 0x93, 0x9c, 0x5b, 0x91, 0x9a, 0x58, 0x8f, 0x97,
+  0x55, 0x8d, 0x96, 0x54, 0x8b, 0x94, 0x51, 0x89, 0x92, 0x4f, 0x87, 0x90,
+  0x4b, 0x85, 0x8e, 0x49, 0x83, 0x8c, 0x47, 0x81, 0x8a, 0x44, 0x7f, 0x88,
+  0x41, 0x7c, 0x86, 0x3f, 0x7b, 0x84, 0x3d, 0x78, 0x81, 0x3b, 0x77, 0x80,
+  0x38, 0x74, 0x7e, 0x35, 0x73, 0x7c, 0x33, 0x70, 0x7a, 0x31, 0x6e, 0x78,
+  0x2f, 0x6c, 0x76, 0x2d, 0x6a, 0x74, 0x3e, 0x77, 0x80, 0x7b, 0xa1, 0xa7,
+  0xbb, 0xce, 0xd2, 0xee, 0xf3, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xde, 0xe6, 0xe7,
-  0xa9, 0xbd, 0xc0, 0x65, 0x89, 0x8e, 0x25, 0x56, 0x5e, 0x11, 0x47, 0x4f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xe2, 0xe9, 0xea, 0xa9, 0xbd, 0xc0, 0x5e, 0x83, 0x89, 0x1e, 0x51, 0x59,
   0x10, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
@@ -6182,21 +6054,21 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x00, 0x14, 0x18, 0x23, 0x40, 0x45, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xb3, 0xcd, 0xd1, 0x6d, 0x9f, 0xa6, 0x6b, 0x9d, 0xa5,
-  0x69, 0x9b, 0xa3, 0x66, 0x99, 0xa1, 0x63, 0x97, 0x9f, 0x60, 0x94, 0x9d,
-  0x5e, 0x93, 0x9b, 0x5c, 0x91, 0x99, 0x59, 0x8f, 0x97, 0x56, 0x8c, 0x95,
-  0x53, 0x8a, 0x92, 0x50, 0x88, 0x91, 0x4d, 0x86, 0x8e, 0x4b, 0x83, 0x8c,
-  0x48, 0x80, 0x8a, 0x45, 0x7f, 0x87, 0x42, 0x7c, 0x85, 0x3f, 0x7a, 0x83,
-  0x3e, 0x78, 0x82, 0x3a, 0x76, 0x7f, 0x37, 0x73, 0x7d, 0x35, 0x71, 0x7b,
-  0x35, 0x70, 0x79, 0x66, 0x92, 0x99, 0xb4, 0xca, 0xcd, 0xf1, 0xf5, 0xf6,
+  0x00, 0x16, 0x19, 0x11, 0x2c, 0x30, 0xe9, 0xed, 0xee, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xc9, 0xdc, 0xdf, 0x68, 0x9b, 0xa3, 0x65, 0x99, 0xa1,
+  0x63, 0x98, 0xa0, 0x60, 0x96, 0x9e, 0x5e, 0x93, 0x9b, 0x5b, 0x91, 0x99,
+  0x59, 0x8f, 0x98, 0x56, 0x8d, 0x96, 0x55, 0x8c, 0x94, 0x52, 0x89, 0x92,
+  0x4e, 0x87, 0x8f, 0x4b, 0x85, 0x8e, 0x49, 0x83, 0x8b, 0x47, 0x81, 0x8a,
+  0x44, 0x7e, 0x87, 0x41, 0x7c, 0x85, 0x3e, 0x79, 0x82, 0x3d, 0x78, 0x81,
+  0x3a, 0x75, 0x7f, 0x37, 0x74, 0x7d, 0x34, 0x71, 0x7b, 0x33, 0x6f, 0x79,
+  0x5d, 0x8d, 0x94, 0xad, 0xc5, 0xc9, 0xee, 0xf3, 0xf4, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xf1, 0xf1, 0xa4, 0xb9, 0xbc,
-  0x4a, 0x73, 0x7a, 0x12, 0x46, 0x4f, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xe9, 0xea,
+  0x92, 0xab, 0xaf, 0x34, 0x61, 0x69, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -6246,21 +6118,21 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x19, 0x1d, 0x01, 0x18, 0x1b, 0x96, 0xa9, 0xac, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xef, 0xf5, 0xf5, 0x7e, 0xaa, 0xb1, 0x6e, 0x9f, 0xa7,
-  0x6c, 0x9d, 0xa5, 0x69, 0x9b, 0xa3, 0x66, 0x99, 0xa1, 0x64, 0x97, 0x9f,
-  0x61, 0x95, 0x9d, 0x5e, 0x92, 0x9a, 0x5c, 0x91, 0x99, 0x59, 0x8e, 0x97,
-  0x56, 0x8c, 0x94, 0x53, 0x8a, 0x92, 0x50, 0x88, 0x90, 0x4d, 0x85, 0x8e,
-  0x4a, 0x82, 0x8b, 0x48, 0x80, 0x89, 0x45, 0x7e, 0x86, 0x42, 0x7c, 0x85,
-  0x3f, 0x79, 0x83, 0x3c, 0x77, 0x80, 0x3a, 0x75, 0x7f, 0x73, 0x9c, 0xa3,
-  0xcd, 0xdc, 0xde, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x19, 0x1d, 0x00, 0x13, 0x17, 0x6e, 0x85, 0x89, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xfc, 0xfd, 0xfd, 0x8c, 0xb3, 0xb9, 0x69, 0x9b, 0xa4,
+  0x66, 0x99, 0xa1, 0x64, 0x98, 0xa0, 0x61, 0x96, 0x9e, 0x5f, 0x93, 0x9b,
+  0x5c, 0x91, 0x9a, 0x59, 0x8f, 0x97, 0x57, 0x8e, 0x96, 0x55, 0x8b, 0x94,
+  0x51, 0x89, 0x91, 0x4e, 0x86, 0x8f, 0x4b, 0x85, 0x8d, 0x49, 0x82, 0x8b,
+  0x46, 0x7f, 0x89, 0x44, 0x7e, 0x87, 0x41, 0x7b, 0x84, 0x3e, 0x79, 0x82,
+  0x3c, 0x76, 0x80, 0x39, 0x75, 0x7e, 0x63, 0x92, 0x9a, 0xc0, 0xd3, 0xd6,
+  0xfc, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xfe, 0xfe, 0xfe, 0xc4, 0xd1, 0xd3, 0x58, 0x7d, 0x83, 0x11, 0x45, 0x4d,
+  0xff, 0xff, 0xff, 0xf7, 0xf8, 0xf9, 0xa5, 0xb9, 0xbc, 0x37, 0x63, 0x69,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -6310,13 +6182,13 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x00, 0x13, 0x16, 0x29, 0x46, 0x4b, 0xfe, 0xfe, 0xfe,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb9, 0xd1, 0xd5, 0x72, 0xa1, 0xa9,
-  0x6f, 0xa0, 0xa7, 0x6c, 0x9e, 0xa5, 0x6a, 0x9b, 0xa3, 0x67, 0x99, 0xa1,
-  0x64, 0x97, 0x9f, 0x61, 0x94, 0x9c, 0x5f, 0x93, 0x9b, 0x5c, 0x90, 0x98,
-  0x58, 0x8e, 0x96, 0x56, 0x8b, 0x94, 0x52, 0x89, 0x91, 0x4f, 0x86, 0x8f,
-  0x4c, 0x84, 0x8d, 0x4a, 0x82, 0x8a, 0x47, 0x7f, 0x88, 0x44, 0x7d, 0x86,
-  0x41, 0x7a, 0x84, 0x66, 0x94, 0x9b, 0xc9, 0xd9, 0xdc, 0xff, 0xff, 0xff,
+  0x02, 0x1a, 0x1e, 0x00, 0x14, 0x17, 0x16, 0x31, 0x34, 0xf2, 0xf6, 0xf6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xdf, 0xe1, 0x6c, 0x9e, 0xa6,
+  0x6a, 0x9c, 0xa4, 0x67, 0x9a, 0xa2, 0x64, 0x98, 0x9f, 0x61, 0x95, 0x9d,
+  0x60, 0x94, 0x9c, 0x5d, 0x91, 0x9a, 0x5a, 0x8f, 0x98, 0x57, 0x8d, 0x95,
+  0x54, 0x8b, 0x93, 0x51, 0x88, 0x91, 0x4e, 0x86, 0x8f, 0x4b, 0x84, 0x8d,
+  0x49, 0x81, 0x8a, 0x46, 0x7f, 0x88, 0x43, 0x7c, 0x85, 0x40, 0x7b, 0x83,
+  0x55, 0x88, 0x91, 0xb7, 0xcc, 0xd0, 0xfc, 0xfd, 0xfd, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -6324,8 +6196,8 @@
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc2, 0xcf, 0xd1,
-  0x47, 0x6e, 0x75, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf8, 0xf8,
+  0x95, 0xac, 0xaf, 0x22, 0x51, 0x58, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -6374,13 +6246,13 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x00, 0x17, 0x1b, 0x03, 0x19, 0x1c, 0xae, 0xbd, 0xbf,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf5, 0xf6, 0x81, 0xab, 0xb2,
-  0x73, 0xa2, 0xa9, 0x70, 0xa0, 0xa7, 0x6d, 0x9e, 0xa5, 0x6b, 0x9b, 0xa3,
-  0x68, 0x99, 0xa1, 0x64, 0x96, 0x9e, 0x62, 0x95, 0x9d, 0x5f, 0x92, 0x9a,
-  0x5b, 0x90, 0x98, 0x58, 0x8d, 0x96, 0x55, 0x8b, 0x93, 0x52, 0x88, 0x91,
-  0x4e, 0x85, 0x8e, 0x4c, 0x84, 0x8c, 0x49, 0x80, 0x89, 0x54, 0x88, 0x90,
-  0xac, 0xc5, 0xc9, 0xfa, 0xfb, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1b, 0x00, 0x14, 0x17, 0x84, 0x98, 0x9c,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfd, 0x8c, 0xb3, 0xb9,
+  0x6d, 0x9e, 0xa6, 0x6b, 0x9d, 0xa4, 0x68, 0x9a, 0xa2, 0x65, 0x98, 0x9f,
+  0x62, 0x96, 0x9e, 0x60, 0x93, 0x9b, 0x5d, 0x91, 0x9a, 0x5a, 0x8f, 0x97,
+  0x57, 0x8d, 0x95, 0x54, 0x8a, 0x93, 0x51, 0x88, 0x90, 0x4e, 0x86, 0x8f,
+  0x4b, 0x83, 0x8c, 0x49, 0x81, 0x8a, 0x46, 0x7e, 0x87, 0x8d, 0xaf, 0xb5,
+  0xef, 0xf4, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -6389,7 +6261,7 @@
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xfb, 0xfc, 0xfc, 0x9a, 0xaf, 0xb3, 0x1e, 0x4d, 0x55, 0x0d, 0x3f, 0x47,
+  0xff, 0xff, 0xff, 0xe2, 0xe8, 0xe9, 0x5d, 0x7f, 0x84, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -6438,12 +6310,12 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x00, 0x11, 0x14, 0x40, 0x5c, 0x5f,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb5, 0xce, 0xd2,
-  0x77, 0xa4, 0xab, 0x74, 0xa3, 0xaa, 0x71, 0xa0, 0xa7, 0x6e, 0x9e, 0xa5,
-  0x6b, 0x9b, 0xa3, 0x68, 0x99, 0xa0, 0x65, 0x97, 0x9f, 0x61, 0x94, 0x9c,
-  0x5e, 0x92, 0x99, 0x5b, 0x8f, 0x98, 0x57, 0x8d, 0x95, 0x54, 0x89, 0x92,
-  0x51, 0x87, 0x90, 0x4e, 0x85, 0x8d, 0x7e, 0xa5, 0xac, 0xe4, 0xed, 0xee,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x00, 0x11, 0x14, 0x26, 0x41, 0x46,
+  0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xda, 0xdd,
+  0x71, 0xa1, 0xa8, 0x6e, 0x9f, 0xa6, 0x6c, 0x9c, 0xa4, 0x69, 0x9a, 0xa2,
+  0x66, 0x98, 0xa0, 0x62, 0x95, 0x9d, 0x60, 0x94, 0x9c, 0x5d, 0x91, 0x99,
+  0x59, 0x8f, 0x96, 0x57, 0x8c, 0x95, 0x54, 0x8a, 0x92, 0x50, 0x87, 0x90,
+  0x4d, 0x84, 0x8d, 0x5b, 0x8d, 0x95, 0xc3, 0xd5, 0xd8, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -6453,8 +6325,8 @@
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xe3, 0xe4, 0x4a, 0x6f, 0x75,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xb3, 0xb6,
+  0x1a, 0x4a, 0x50, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -6502,23 +6374,23 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x00, 0x14, 0x18, 0x0a, 0x21, 0x25,
-  0xdb, 0xe1, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0xf0, 0xf1,
-  0x80, 0xab, 0xb1, 0x78, 0xa5, 0xac, 0x74, 0xa2, 0xa9, 0x71, 0xa0, 0xa7,
-  0x6e, 0x9e, 0xa5, 0x6b, 0x9b, 0xa2, 0x67, 0x98, 0xa0, 0x65, 0x96, 0x9e,
-  0x61, 0x94, 0x9b, 0x5d, 0x91, 0x99, 0x5a, 0x8f, 0x96, 0x57, 0x8b, 0x94,
-  0x58, 0x8c, 0x94, 0xae, 0xc7, 0xcb, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x00, 0x15, 0x19, 0x04, 0x18, 0x1b,
+  0xb6, 0xc3, 0xc4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xf8, 0xf9,
+  0x85, 0xad, 0xb4, 0x72, 0xa1, 0xa9, 0x6f, 0x9f, 0xa6, 0x6c, 0x9c, 0xa4,
+  0x69, 0x9a, 0xa2, 0x66, 0x97, 0x9f, 0x63, 0x96, 0x9e, 0x60, 0x92, 0x9b,
+  0x5c, 0x91, 0x98, 0x59, 0x8e, 0x96, 0x56, 0x8b, 0x93, 0x53, 0x89, 0x92,
+  0x74, 0x9f, 0xa6, 0xe4, 0xec, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfc, 0xfd,
-  0xf5, 0xf7, 0xf8, 0xee, 0xf3, 0xf3, 0xea, 0xef, 0xf0, 0xea, 0xef, 0xf0,
-  0xf0, 0xf4, 0xf4, 0xf5, 0xf8, 0xf8, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfb, 0xfb, 0xeb, 0xf0, 0xf1,
+  0xd6, 0xe1, 0xe2, 0xc4, 0xd4, 0xd6, 0xba, 0xcc, 0xcf, 0xb8, 0xcb, 0xce,
+  0xc0, 0xd0, 0xd3, 0xce, 0xdb, 0xdd, 0xe6, 0xec, 0xed, 0xf5, 0xf7, 0xf8,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xfb, 0xfb,
-  0x7b, 0x96, 0x9a, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xcf, 0xd9, 0xda, 0x34, 0x5d, 0x63, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -6566,23 +6438,23 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x16, 0x1a, 0x00, 0x10, 0x13,
-  0x6a, 0x82, 0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xaa, 0xc6, 0xcb, 0x7a, 0xa7, 0xae, 0x78, 0xa4, 0xab, 0x75, 0xa2, 0xa9,
-  0x71, 0xa0, 0xa7, 0x6e, 0x9d, 0xa4, 0x6b, 0x9b, 0xa2, 0x68, 0x98, 0xa0,
-  0x64, 0x96, 0x9d, 0x60, 0x92, 0x9a, 0x5d, 0x91, 0x98, 0x69, 0x98, 0xa0,
-  0xd1, 0xdf, 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x00, 0x0f, 0x12,
+  0x4b, 0x65, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xb6, 0xcf, 0xd3, 0x76, 0xa4, 0xab, 0x72, 0xa1, 0xa8, 0x6f, 0x9e, 0xa6,
+  0x6c, 0x9c, 0xa4, 0x69, 0x99, 0xa1, 0x66, 0x97, 0x9f, 0x63, 0x95, 0x9d,
+  0x5f, 0x92, 0x9a, 0x5c, 0x90, 0x98, 0x58, 0x8d, 0x95, 0x88, 0xae, 0xb3,
+  0xf3, 0xf7, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xf7, 0xf8,
-  0xc8, 0xd7, 0xda, 0x98, 0xb5, 0xb9, 0x72, 0x97, 0x9e, 0x52, 0x80, 0x87,
-  0x3b, 0x6f, 0x77, 0x2d, 0x65, 0x6d, 0x29, 0x61, 0x6a, 0x27, 0x5f, 0x68,
-  0x29, 0x60, 0x69, 0x39, 0x6c, 0x73, 0x4f, 0x7b, 0x83, 0x6e, 0x92, 0x98,
-  0x95, 0xb0, 0xb3, 0xc7, 0xd5, 0xd7, 0xf4, 0xf7, 0xf7, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfc, 0xd5, 0xe1, 0xe3,
+  0x9d, 0xb9, 0xbd, 0x70, 0x97, 0x9d, 0x4a, 0x7b, 0x83, 0x2d, 0x65, 0x6f,
+  0x24, 0x5f, 0x67, 0x1f, 0x5a, 0x64, 0x1d, 0x59, 0x62, 0x1b, 0x56, 0x60,
+  0x1a, 0x55, 0x5e, 0x1c, 0x56, 0x5f, 0x20, 0x58, 0x62, 0x37, 0x69, 0x71,
+  0x5c, 0x84, 0x8a, 0x89, 0xa5, 0xaa, 0xc2, 0xd1, 0xd4, 0xf5, 0xf7, 0xf8,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0x9d, 0xb1, 0xb4, 0x13, 0x42, 0x49, 0x0d, 0x3c, 0x44,
+  0xff, 0xff, 0xff, 0xe7, 0xec, 0xed, 0x4a, 0x6e, 0x74, 0x11, 0x3f, 0x47,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -6630,23 +6502,23 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x00, 0x10, 0x13,
-  0x1f, 0x39, 0x3d, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xda, 0xe7, 0xe9, 0x7e, 0xa9, 0xb0, 0x7b, 0xa7, 0xae, 0x78, 0xa4, 0xab,
-  0x74, 0xa1, 0xa9, 0x71, 0x9f, 0xa6, 0x6d, 0x9c, 0xa4, 0x6a, 0x99, 0xa1,
-  0x66, 0x97, 0x9f, 0x63, 0x94, 0x9c, 0x79, 0xa4, 0xa9, 0xe4, 0xed, 0xee,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x00, 0x11, 0x14,
+  0x10, 0x28, 0x2c, 0xeb, 0xee, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xe6, 0xee, 0xef, 0x7d, 0xa9, 0xb0, 0x76, 0xa3, 0xaa, 0x73, 0xa1, 0xa8,
+  0x6f, 0x9e, 0xa6, 0x6c, 0x9c, 0xa3, 0x6a, 0x9a, 0xa2, 0x66, 0x97, 0x9f,
+  0x62, 0x94, 0x9c, 0x5f, 0x92, 0x9a, 0x94, 0xb6, 0xbb, 0xfb, 0xfc, 0xfd,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xfc, 0xfd, 0xfd, 0xc9, 0xd8, 0xda, 0x81, 0xa4, 0xaa, 0x42, 0x78, 0x80,
-  0x29, 0x65, 0x6e, 0x27, 0x62, 0x6c, 0x25, 0x5f, 0x69, 0x24, 0x5f, 0x68,
-  0x23, 0x5d, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x59, 0x63, 0x1d, 0x58, 0x61,
-  0x1b, 0x55, 0x5f, 0x1a, 0x55, 0x5d, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
-  0x17, 0x51, 0x59, 0x17, 0x50, 0x59, 0x31, 0x63, 0x6b, 0x70, 0x93, 0x98,
-  0xbe, 0xce, 0xd0, 0xfa, 0xfb, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xe2, 0xea, 0xec, 0x99, 0xb6, 0xba, 0x53, 0x83, 0x8b, 0x2c, 0x67, 0x70,
+  0x28, 0x64, 0x6d, 0x26, 0x61, 0x6b, 0x25, 0x5f, 0x69, 0x24, 0x5f, 0x68,
+  0x21, 0x5c, 0x65, 0x20, 0x5b, 0x64, 0x1d, 0x59, 0x62, 0x1c, 0x57, 0x61,
+  0x1b, 0x55, 0x5f, 0x19, 0x54, 0x5d, 0x18, 0x52, 0x5c, 0x17, 0x51, 0x5a,
+  0x17, 0x50, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x32, 0x64, 0x6b,
+  0x7a, 0x99, 0x9e, 0xd0, 0xdb, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb4, 0xc3, 0xc5, 0x54, 0x75, 0x7b,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xee, 0xf1, 0xf2, 0x8d, 0xa3, 0xa7,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -6695,22 +6567,22 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x01, 0x14, 0x17,
-  0x03, 0x15, 0x19, 0xb8, 0xc4, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xfb, 0xfc, 0xfd, 0x97, 0xba, 0xbf, 0x7e, 0xa9, 0xaf, 0x7a, 0xa6, 0xad,
-  0x78, 0xa4, 0xab, 0x74, 0xa1, 0xa8, 0x70, 0x9e, 0xa6, 0x6c, 0x9b, 0xa3,
-  0x69, 0x99, 0xa0, 0x81, 0xa9, 0xb0, 0xec, 0xf2, 0xf3, 0xff, 0xff, 0xff,
+  0x00, 0x12, 0x15, 0x91, 0xa4, 0xa7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x9f, 0xc0, 0xc5, 0x79, 0xa6, 0xad, 0x76, 0xa3, 0xaa,
+  0x73, 0xa1, 0xa8, 0x6f, 0x9e, 0xa5, 0x6c, 0x9b, 0xa3, 0x68, 0x98, 0xa0,
+  0x64, 0x96, 0x9d, 0x98, 0xb9, 0xbe, 0xfc, 0xfd, 0xfd, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfc, 0xb9, 0xcd, 0xd1,
-  0x5f, 0x8d, 0x94, 0x33, 0x6d, 0x76, 0x2f, 0x69, 0x73, 0x2c, 0x67, 0x70,
-  0x2a, 0x65, 0x6e, 0x27, 0x62, 0x6c, 0x26, 0x60, 0x6a, 0x24, 0x5f, 0x68,
-  0x23, 0x5d, 0x66, 0x21, 0x5c, 0x65, 0x1f, 0x5a, 0x63, 0x1d, 0x58, 0x61,
-  0x1c, 0x56, 0x60, 0x1b, 0x55, 0x5e, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
-  0x17, 0x51, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x15, 0x4d, 0x56,
-  0x14, 0x4c, 0x54, 0x40, 0x6d, 0x74, 0xa4, 0xb9, 0xbd, 0xf7, 0xf9, 0xf9,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xe7, 0xe8, 0x82, 0xa6, 0xac,
+  0x3d, 0x73, 0x7c, 0x2f, 0x6a, 0x73, 0x2d, 0x68, 0x72, 0x2b, 0x67, 0x70,
+  0x29, 0x65, 0x6e, 0x26, 0x62, 0x6c, 0x25, 0x5f, 0x69, 0x24, 0x5f, 0x68,
+  0x22, 0x5c, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x59, 0x63, 0x1d, 0x58, 0x61,
+  0x1b, 0x55, 0x5f, 0x1a, 0x55, 0x5d, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
+  0x17, 0x51, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x14, 0x4d, 0x55,
+  0x14, 0x4c, 0x54, 0x17, 0x4d, 0x56, 0x59, 0x7f, 0x85, 0xc5, 0xd3, 0xd4,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xbe, 0xc1,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0xc0, 0xc2,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -6759,20 +6631,20 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x00, 0x0e, 0x11, 0x53, 0x6c, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xc1, 0xd6, 0xd9, 0x82, 0xab, 0xb2, 0x7e, 0xa8, 0xaf,
-  0x7a, 0xa6, 0xad, 0x77, 0xa3, 0xaa, 0x73, 0xa0, 0xa7, 0x6f, 0x9d, 0xa4,
-  0x85, 0xac, 0xb2, 0xed, 0xf3, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x0e, 0x10, 0x3a, 0x54, 0x59, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xcd, 0xde, 0xe1, 0x7c, 0xa8, 0xae, 0x79, 0xa5, 0xac,
+  0x76, 0xa3, 0xaa, 0x72, 0xa0, 0xa7, 0x6e, 0x9d, 0xa4, 0x6c, 0x9b, 0xa2,
+  0x92, 0xb5, 0xba, 0xfa, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xcd, 0xdb, 0xde, 0x66, 0x93, 0x9a, 0x39, 0x72, 0x7b,
-  0x36, 0x6f, 0x78, 0x33, 0x6d, 0x76, 0x30, 0x6a, 0x74, 0x2d, 0x68, 0x71,
-  0x2b, 0x66, 0x6f, 0x28, 0x63, 0x6d, 0x27, 0x61, 0x6b, 0x26, 0x61, 0x6a,
-  0x24, 0x5e, 0x67, 0x22, 0x5c, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x58, 0x62,
-  0x1c, 0x56, 0x60, 0x1b, 0x55, 0x5e, 0x1a, 0x54, 0x5d, 0x18, 0x51, 0x5b,
-  0x17, 0x51, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4f, 0x58, 0x15, 0x4d, 0x56,
-  0x14, 0x4c, 0x54, 0x13, 0x4a, 0x53, 0x13, 0x49, 0x52, 0x3a, 0x67, 0x6e,
-  0xb2, 0xc4, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xee, 0xf3, 0xf4, 0x91, 0xb1, 0xb6, 0x41, 0x78, 0x81, 0x36, 0x70, 0x79,
+  0x33, 0x6d, 0x76, 0x31, 0x6c, 0x74, 0x2e, 0x69, 0x72, 0x2c, 0x67, 0x70,
+  0x29, 0x65, 0x6e, 0x27, 0x62, 0x6c, 0x26, 0x60, 0x6a, 0x24, 0x5f, 0x68,
+  0x22, 0x5c, 0x66, 0x21, 0x5c, 0x65, 0x1e, 0x59, 0x63, 0x1d, 0x58, 0x61,
+  0x1b, 0x55, 0x5f, 0x1a, 0x55, 0x5d, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
+  0x17, 0x51, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x14, 0x4d, 0x55,
+  0x14, 0x4c, 0x54, 0x13, 0x4a, 0x53, 0x13, 0x49, 0x52, 0x14, 0x49, 0x51,
+  0x63, 0x86, 0x8c, 0xde, 0xe5, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -6823,21 +6695,85 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x00, 0x0f, 0x11, 0x1a, 0x32, 0x36, 0xf8, 0xfa, 0xfa, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xe6, 0xef, 0xf0, 0x87, 0xaf, 0xb5, 0x81, 0xaa, 0xb1,
-  0x7d, 0xa8, 0xae, 0x79, 0xa5, 0xab, 0x76, 0xa2, 0xa9, 0x81, 0xa9, 0xaf,
-  0xe8, 0xef, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x11, 0x12, 0x0e, 0x25, 0x28, 0xe6, 0xec, 0xec, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xf0, 0xf5, 0xf6, 0x8a, 0xb1, 0xb7, 0x7c, 0xa7, 0xae,
+  0x78, 0xa5, 0xab, 0x75, 0xa1, 0xa9, 0x72, 0xa0, 0xa7, 0x86, 0xad, 0xb3,
+  0xf2, 0xf6, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf7, 0xf7,
-  0x91, 0xb2, 0xb7, 0x42, 0x79, 0x81, 0x3d, 0x75, 0x7e, 0x3a, 0x72, 0x7c,
-  0x37, 0x70, 0x79, 0x34, 0x6e, 0x76, 0x31, 0x6b, 0x74, 0x2e, 0x69, 0x72,
-  0x2c, 0x67, 0x6f, 0x2a, 0x64, 0x6e, 0x28, 0x62, 0x6c, 0x26, 0x60, 0x69,
-  0x24, 0x5e, 0x67, 0x22, 0x5c, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x58, 0x62,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xd5, 0xd8,
+  0x57, 0x89, 0x91, 0x3e, 0x76, 0x7f, 0x3b, 0x74, 0x7d, 0x38, 0x71, 0x7a,
+  0x35, 0x6e, 0x78, 0x32, 0x6c, 0x75, 0x2f, 0x69, 0x73, 0x2d, 0x68, 0x71,
+  0x2a, 0x65, 0x6e, 0x28, 0x63, 0x6d, 0x26, 0x61, 0x6b, 0x25, 0x5f, 0x69,
+  0x23, 0x5d, 0x66, 0x22, 0x5c, 0x66, 0x1f, 0x5a, 0x63, 0x1e, 0x58, 0x62,
+  0x1c, 0x56, 0x60, 0x1b, 0x55, 0x5e, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
+  0x17, 0x51, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x15, 0x4d, 0x56,
+  0x14, 0x4c, 0x54, 0x13, 0x4a, 0x53, 0x13, 0x49, 0x52, 0x12, 0x48, 0x50,
+  0x11, 0x47, 0x50, 0x22, 0x53, 0x5b, 0xa0, 0xb5, 0xb8, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x01, 0x13, 0x16, 0x00, 0x11, 0x14, 0x9b, 0xac, 0xae, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa9, 0xc5, 0xca, 0x7f, 0xa9, 0xaf,
+  0x7c, 0xa7, 0xae, 0x78, 0xa4, 0xab, 0x7e, 0xa7, 0xaf, 0xe1, 0xea, 0xec,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfc, 0x98, 0xb7, 0xbc, 0x44, 0x7b, 0x85,
+  0x42, 0x7a, 0x83, 0x3f, 0x77, 0x80, 0x3c, 0x75, 0x7e, 0x39, 0x72, 0x7b,
+  0x36, 0x6f, 0x78, 0x33, 0x6d, 0x76, 0x31, 0x6b, 0x74, 0x2e, 0x69, 0x72,
+  0x2b, 0x66, 0x6f, 0x29, 0x64, 0x6e, 0x27, 0x61, 0x6b, 0x26, 0x60, 0x69,
+  0x24, 0x5e, 0x67, 0x22, 0x5c, 0x66, 0x1f, 0x5a, 0x63, 0x1e, 0x58, 0x62,
   0x1d, 0x57, 0x60, 0x1b, 0x55, 0x5e, 0x1a, 0x54, 0x5d, 0x19, 0x52, 0x5c,
   0x18, 0x51, 0x5a, 0x17, 0x50, 0x58, 0x16, 0x4f, 0x58, 0x15, 0x4d, 0x56,
   0x14, 0x4c, 0x54, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x12, 0x48, 0x50,
-  0x11, 0x47, 0x50, 0x61, 0x84, 0x8a, 0xe5, 0xea, 0xeb, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x11, 0x47, 0x50, 0x10, 0x45, 0x4e, 0x10, 0x44, 0x4d, 0x67, 0x88, 0x8d,
+  0xf2, 0xf5, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -6887,21 +6823,85 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x01, 0x12, 0x15, 0x03, 0x14, 0x17, 0xbb, 0xc8, 0xc9, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0xc0, 0xc4, 0x84, 0xac, 0xb2,
-  0x80, 0xa9, 0xb0, 0x7c, 0xa6, 0xad, 0x7d, 0xa8, 0xae, 0xda, 0xe6, 0xe8,
+  0x02, 0x13, 0x16, 0x00, 0x0d, 0x0f, 0x47, 0x61, 0x65, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xe0, 0xe2, 0x83, 0xab, 0xb2,
+  0x7f, 0xa9, 0xaf, 0x7b, 0xa6, 0xad, 0xcb, 0xdb, 0xde, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xe7, 0xe9, 0x68, 0x94, 0x9d,
-  0x44, 0x7b, 0x84, 0x41, 0x79, 0x81, 0x3f, 0x77, 0x80, 0x3b, 0x73, 0x7c,
-  0x38, 0x70, 0x7a, 0x34, 0x6e, 0x77, 0x32, 0x6b, 0x75, 0x30, 0x6a, 0x73,
-  0x2d, 0x67, 0x70, 0x2a, 0x64, 0x6e, 0x28, 0x62, 0x6c, 0x26, 0x61, 0x6a,
-  0x25, 0x5e, 0x68, 0x23, 0x5d, 0x66, 0x20, 0x5b, 0x64, 0x1f, 0x59, 0x62,
+  0xf1, 0xf5, 0xf6, 0x7d, 0xa5, 0xab, 0x4b, 0x81, 0x8a, 0x46, 0x7d, 0x86,
+  0x43, 0x7b, 0x83, 0x40, 0x78, 0x81, 0x3e, 0x76, 0x7f, 0x3b, 0x73, 0x7c,
+  0x38, 0x70, 0x7a, 0x34, 0x6e, 0x77, 0x32, 0x6b, 0x75, 0x2f, 0x69, 0x72,
+  0x2c, 0x67, 0x6f, 0x2a, 0x64, 0x6e, 0x28, 0x62, 0x6c, 0x26, 0x60, 0x69,
+  0x24, 0x5e, 0x67, 0x23, 0x5d, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x58, 0x62,
   0x1d, 0x57, 0x60, 0x1c, 0x56, 0x5f, 0x1a, 0x54, 0x5d, 0x19, 0x52, 0x5c,
+  0x18, 0x51, 0x5a, 0x16, 0x4f, 0x58, 0x16, 0x4f, 0x58, 0x15, 0x4d, 0x56,
+  0x14, 0x4c, 0x54, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x13, 0x49, 0x51,
+  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0x10, 0x44, 0x4c,
+  0x45, 0x6d, 0x73, 0xe4, 0xe9, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x00, 0x0d, 0x10, 0x1a, 0x32, 0x36, 0xfb, 0xfd, 0xfd,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xf3, 0xf4, 0x8c, 0xb2, 0xb7,
+  0x82, 0xab, 0xb1, 0xac, 0xc7, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed, 0xf2, 0xf3,
+  0x76, 0x9f, 0xa6, 0x4e, 0x84, 0x8c, 0x4c, 0x81, 0x8a, 0x48, 0x7e, 0x87,
+  0x45, 0x7c, 0x85, 0x42, 0x79, 0x82, 0x3f, 0x77, 0x80, 0x3c, 0x74, 0x7d,
+  0x39, 0x71, 0x7a, 0x35, 0x6f, 0x77, 0x33, 0x6c, 0x76, 0x30, 0x6a, 0x73,
+  0x2e, 0x68, 0x71, 0x2b, 0x65, 0x6f, 0x29, 0x63, 0x6d, 0x27, 0x61, 0x6a,
+  0x25, 0x5e, 0x68, 0x23, 0x5d, 0x66, 0x20, 0x5b, 0x64, 0x1f, 0x59, 0x62,
+  0x1e, 0x57, 0x61, 0x1c, 0x56, 0x5f, 0x1b, 0x54, 0x5e, 0x19, 0x52, 0x5c,
   0x18, 0x51, 0x5a, 0x17, 0x50, 0x58, 0x16, 0x4f, 0x58, 0x15, 0x4d, 0x56,
   0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x13, 0x49, 0x51,
-  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x2d, 0x5b, 0x63, 0xe2, 0xe8, 0xe9,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0x10, 0x44, 0x4c,
+  0x10, 0x43, 0x4b, 0x38, 0x62, 0x68, 0xdf, 0xe6, 0xe7, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -6951,85 +6951,21 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x01, 0x13, 0x16, 0x00, 0x0e, 0x10, 0x5d, 0x75, 0x79, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc6, 0xd9, 0xdc, 0x86, 0xae, 0xb4,
-  0x83, 0xab, 0xb2, 0x7f, 0xa8, 0xaf, 0xc6, 0xd8, 0xdb, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x00, 0x11, 0x13, 0x04, 0x16, 0x19, 0xcb, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xbe, 0xc3,
+  0x8d, 0xb3, 0xb9, 0xf1, 0xf6, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xc8, 0xd9, 0xdc, 0x59, 0x8a, 0x93, 0x49, 0x7f, 0x88,
-  0x46, 0x7d, 0x85, 0x42, 0x79, 0x82, 0x40, 0x77, 0x80, 0x3d, 0x74, 0x7e,
-  0x39, 0x71, 0x7a, 0x35, 0x6f, 0x77, 0x34, 0x6d, 0x76, 0x31, 0x6b, 0x73,
-  0x2e, 0x68, 0x71, 0x2c, 0x66, 0x6f, 0x2a, 0x63, 0x6d, 0x27, 0x61, 0x6a,
-  0x25, 0x5e, 0x68, 0x24, 0x5e, 0x67, 0x21, 0x5b, 0x65, 0x20, 0x5a, 0x63,
-  0x1e, 0x57, 0x61, 0x1c, 0x56, 0x5f, 0x1b, 0x54, 0x5e, 0x1a, 0x53, 0x5c,
-  0x18, 0x51, 0x5a, 0x17, 0x50, 0x58, 0x16, 0x4f, 0x58, 0x16, 0x4e, 0x57,
-  0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x13, 0x49, 0x51,
-  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0xc8, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x00, 0x0d, 0x0f, 0x27, 0x3f, 0x44, 0xfe, 0xfe, 0xfe,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xed, 0xee, 0x8a, 0xb1, 0xb7,
-  0x85, 0xad, 0xb3, 0xab, 0xc6, 0xca, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xc1, 0xd4, 0xd7, 0x56, 0x89, 0x91, 0x4d, 0x83, 0x8c, 0x4b, 0x80, 0x89,
-  0x47, 0x7d, 0x86, 0x44, 0x7b, 0x83, 0x40, 0x78, 0x81, 0x3e, 0x75, 0x7e,
-  0x3b, 0x72, 0x7b, 0x37, 0x70, 0x79, 0x34, 0x6d, 0x77, 0x32, 0x6b, 0x74,
-  0x2f, 0x69, 0x71, 0x2c, 0x66, 0x6f, 0x2a, 0x63, 0x6d, 0x27, 0x61, 0x6a,
-  0x26, 0x5f, 0x68, 0x24, 0x5e, 0x67, 0x21, 0x5b, 0x65, 0x20, 0x5a, 0x63,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf4, 0xf5, 0x79, 0xa2, 0xa8,
+  0x55, 0x88, 0x91, 0x50, 0x85, 0x8d, 0x4d, 0x82, 0x8b, 0x4a, 0x7f, 0x88,
+  0x46, 0x7d, 0x85, 0x43, 0x7a, 0x83, 0x40, 0x78, 0x81, 0x3d, 0x74, 0x7e,
+  0x3a, 0x72, 0x7b, 0x36, 0x70, 0x78, 0x34, 0x6d, 0x76, 0x31, 0x6b, 0x73,
+  0x2e, 0x68, 0x71, 0x2c, 0x66, 0x6f, 0x2a, 0x63, 0x6d, 0x28, 0x62, 0x6b,
+  0x26, 0x5f, 0x68, 0x24, 0x5e, 0x67, 0x22, 0x5c, 0x65, 0x1f, 0x59, 0x62,
   0x1e, 0x57, 0x61, 0x1d, 0x57, 0x5f, 0x1b, 0x54, 0x5e, 0x1a, 0x53, 0x5c,
   0x19, 0x52, 0x5b, 0x17, 0x50, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
-  0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0xc9, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x13, 0x49, 0x51,
+  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0x10, 0x44, 0x4c,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x3a, 0x63, 0x6a, 0xe7, 0xec, 0xed,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -7079,22 +7015,22 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x00, 0x10, 0x12, 0x09, 0x1c, 0x20, 0xdb, 0xe1, 0xe2,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfd, 0xfd, 0x9a, 0xbc, 0xc0,
-  0x90, 0xb4, 0xba, 0xef, 0xf4, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0d, 0x0f, 0x80, 0x94, 0x97,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbe, 0xd3, 0xd7,
+  0xc7, 0xda, 0xdc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xd8, 0xdb,
-  0x5a, 0x8c, 0x94, 0x53, 0x87, 0x8f, 0x4f, 0x84, 0x8d, 0x4c, 0x81, 0x8a,
-  0x48, 0x7e, 0x86, 0x45, 0x7b, 0x84, 0x42, 0x79, 0x82, 0x3f, 0x76, 0x7f,
-  0x3c, 0x73, 0x7c, 0x38, 0x71, 0x79, 0x35, 0x6e, 0x77, 0x33, 0x6c, 0x75,
-  0x30, 0x69, 0x72, 0x2d, 0x66, 0x70, 0x2b, 0x64, 0x6e, 0x28, 0x62, 0x6b,
-  0x26, 0x60, 0x69, 0x25, 0x5e, 0x68, 0x23, 0x5d, 0x66, 0x21, 0x5a, 0x64,
-  0x1f, 0x58, 0x62, 0x1d, 0x57, 0x5f, 0x1c, 0x55, 0x5f, 0x1a, 0x53, 0x5c,
+  0xff, 0xff, 0xff, 0xf8, 0xfa, 0xfb, 0x86, 0xab, 0xb1, 0x5a, 0x8d, 0x94,
+  0x57, 0x89, 0x92, 0x52, 0x87, 0x8f, 0x4e, 0x83, 0x8c, 0x4b, 0x80, 0x89,
+  0x48, 0x7e, 0x86, 0x44, 0x7b, 0x83, 0x41, 0x79, 0x81, 0x3f, 0x76, 0x7f,
+  0x3c, 0x73, 0x7c, 0x37, 0x70, 0x79, 0x34, 0x6d, 0x77, 0x32, 0x6b, 0x74,
+  0x2f, 0x69, 0x71, 0x2d, 0x66, 0x70, 0x2a, 0x63, 0x6d, 0x28, 0x62, 0x6b,
+  0x26, 0x5f, 0x68, 0x24, 0x5e, 0x67, 0x22, 0x5c, 0x65, 0x20, 0x5a, 0x63,
+  0x1e, 0x57, 0x61, 0x1d, 0x57, 0x5f, 0x1c, 0x55, 0x5f, 0x1a, 0x53, 0x5c,
   0x19, 0x52, 0x5b, 0x17, 0x50, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
   0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0x10, 0x44, 0x4c,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x4e, 0x72, 0x78,
+  0xf6, 0xf8, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -7143,22 +7079,22 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x11, 0x14, 0x00, 0x0f, 0x12, 0x9c, 0xac, 0xae,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb5, 0xcd, 0xd1,
-  0xc8, 0xda, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0b, 0x0d, 0x41, 0x5a, 0x5e,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xf6, 0xf6,
+  0xf6, 0xf9, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0xe2, 0xe4, 0x64, 0x93, 0x9b,
-  0x59, 0x8b, 0x94, 0x55, 0x89, 0x90, 0x51, 0x85, 0x8e, 0x4d, 0x82, 0x8b,
-  0x4a, 0x7f, 0x88, 0x46, 0x7c, 0x84, 0x43, 0x7a, 0x83, 0x40, 0x77, 0x80,
-  0x3d, 0x74, 0x7d, 0x39, 0x72, 0x7a, 0x36, 0x6f, 0x78, 0x34, 0x6d, 0x75,
-  0x31, 0x6a, 0x73, 0x2e, 0x67, 0x71, 0x2b, 0x64, 0x6e, 0x29, 0x63, 0x6c,
-  0x27, 0x60, 0x6a, 0x25, 0x5e, 0x68, 0x22, 0x5c, 0x65, 0x21, 0x5a, 0x64,
-  0x20, 0x59, 0x62, 0x1d, 0x57, 0x5f, 0x1c, 0x55, 0x5f, 0x1b, 0x53, 0x5d,
+  0xff, 0xff, 0xff, 0xa0, 0xbd, 0xc1, 0x60, 0x90, 0x98, 0x5c, 0x8e, 0x95,
+  0x58, 0x8b, 0x93, 0x54, 0x88, 0x90, 0x50, 0x85, 0x8d, 0x4d, 0x81, 0x8a,
+  0x49, 0x7f, 0x87, 0x46, 0x7c, 0x84, 0x42, 0x79, 0x82, 0x40, 0x76, 0x7f,
+  0x3d, 0x74, 0x7d, 0x38, 0x71, 0x79, 0x35, 0x6e, 0x77, 0x33, 0x6c, 0x75,
+  0x30, 0x69, 0x72, 0x2d, 0x66, 0x70, 0x2b, 0x64, 0x6e, 0x29, 0x63, 0x6c,
+  0x26, 0x60, 0x69, 0x25, 0x5e, 0x68, 0x23, 0x5d, 0x66, 0x20, 0x5a, 0x63,
+  0x1f, 0x58, 0x62, 0x1e, 0x57, 0x60, 0x1c, 0x55, 0x5f, 0x1a, 0x53, 0x5c,
   0x19, 0x52, 0x5b, 0x17, 0x50, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
-  0x15, 0x4c, 0x55, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
+  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x75, 0x92, 0x96, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -7207,86 +7143,86 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0b, 0x0e, 0x50, 0x6a, 0x6e,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xf2, 0xf3,
-  0xf5, 0xf8, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xeb, 0xf1, 0xf2, 0x75, 0x9e, 0xa5, 0x5f, 0x90, 0x97,
-  0x5b, 0x8c, 0x95, 0x56, 0x89, 0x91, 0x52, 0x86, 0x8f, 0x4f, 0x83, 0x8c,
-  0x4c, 0x81, 0x89, 0x48, 0x7d, 0x86, 0x44, 0x7b, 0x83, 0x40, 0x77, 0x80,
-  0x3e, 0x74, 0x7d, 0x3a, 0x72, 0x7b, 0x37, 0x6f, 0x79, 0x34, 0x6d, 0x76,
-  0x32, 0x6b, 0x73, 0x2f, 0x68, 0x71, 0x2c, 0x65, 0x6f, 0x2a, 0x63, 0x6c,
-  0x27, 0x60, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x67, 0x22, 0x5b, 0x64,
-  0x1f, 0x58, 0x62, 0x1e, 0x57, 0x60, 0x1d, 0x56, 0x5f, 0x1b, 0x53, 0x5d,
-  0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
-  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0b, 0x0d, 0x28, 0x41, 0x44,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0b, 0x0d, 0x1f, 0x37, 0x3a,
   0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xfd, 0xfe, 0xfe, 0x95, 0xb6, 0xbb, 0x64, 0x94, 0x9b, 0x61, 0x91, 0x98,
-  0x5c, 0x8d, 0x95, 0x58, 0x8b, 0x92, 0x54, 0x87, 0x90, 0x50, 0x84, 0x8d,
-  0x4d, 0x81, 0x8a, 0x49, 0x7e, 0x86, 0x45, 0x7b, 0x84, 0x42, 0x78, 0x81,
-  0x40, 0x76, 0x7f, 0x3b, 0x73, 0x7b, 0x38, 0x70, 0x79, 0x35, 0x6e, 0x77,
-  0x32, 0x6b, 0x73, 0x30, 0x68, 0x72, 0x2d, 0x65, 0x6f, 0x2a, 0x63, 0x6c,
-  0x29, 0x62, 0x6b, 0x26, 0x60, 0x69, 0x23, 0x5d, 0x66, 0x22, 0x5b, 0x64,
-  0x20, 0x59, 0x62, 0x1f, 0x58, 0x61, 0x1d, 0x56, 0x5f, 0x1b, 0x53, 0x5d,
+  0xc7, 0xd8, 0xdb, 0x66, 0x96, 0x9d, 0x62, 0x92, 0x99, 0x5e, 0x8f, 0x97,
+  0x5a, 0x8c, 0x94, 0x56, 0x89, 0x91, 0x52, 0x86, 0x8f, 0x4e, 0x83, 0x8c,
+  0x4b, 0x80, 0x88, 0x47, 0x7d, 0x85, 0x43, 0x7a, 0x83, 0x40, 0x77, 0x80,
+  0x3e, 0x74, 0x7d, 0x39, 0x72, 0x7a, 0x36, 0x6f, 0x78, 0x34, 0x6d, 0x75,
+  0x31, 0x6a, 0x73, 0x2e, 0x67, 0x71, 0x2c, 0x65, 0x6f, 0x29, 0x63, 0x6c,
+  0x27, 0x60, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x67, 0x22, 0x5b, 0x64,
+  0x20, 0x59, 0x62, 0x1e, 0x57, 0x60, 0x1c, 0x55, 0x5f, 0x1b, 0x53, 0x5d,
+  0x19, 0x52, 0x5b, 0x17, 0x50, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
+  0x15, 0x4c, 0x55, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
+  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0xb4, 0xc3, 0xc5, 0xff, 0xff, 0xff, 0xae, 0xbe, 0xc1,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0e, 0x10, 0x0a, 0x1c, 0x1f,
+  0xdb, 0xe1, 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf5, 0xf6,
+  0x7b, 0xa3, 0xab, 0x68, 0x97, 0x9e, 0x64, 0x93, 0x9a, 0x60, 0x90, 0x98,
+  0x5b, 0x8c, 0x95, 0x57, 0x8a, 0x92, 0x53, 0x87, 0x8f, 0x4f, 0x83, 0x8c,
+  0x4c, 0x81, 0x89, 0x48, 0x7d, 0x86, 0x44, 0x7b, 0x83, 0x41, 0x78, 0x81,
+  0x3f, 0x75, 0x7e, 0x3a, 0x72, 0x7b, 0x37, 0x6f, 0x79, 0x34, 0x6d, 0x76,
+  0x32, 0x6b, 0x73, 0x2f, 0x68, 0x71, 0x2c, 0x65, 0x6f, 0x2a, 0x63, 0x6c,
+  0x28, 0x61, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x67, 0x22, 0x5b, 0x64,
+  0x20, 0x59, 0x62, 0x1e, 0x57, 0x60, 0x1d, 0x56, 0x5f, 0x1b, 0x53, 0x5d,
   0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
   0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
+  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x32, 0x5c, 0x61, 0xee, 0xf1, 0xf2, 0xb8, 0xc6, 0xc8,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -7335,22 +7271,22 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0e, 0x0f, 0x10, 0x24, 0x27,
-  0xe8, 0xec, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x12, 0x01, 0x0e, 0x11,
+  0xb5, 0xc1, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xbf, 0xd3, 0xd6, 0x6a, 0x98, 0x9f, 0x66, 0x95, 0x9c, 0x62, 0x92, 0x99,
-  0x5e, 0x8e, 0x97, 0x5a, 0x8c, 0x94, 0x55, 0x88, 0x90, 0x51, 0x85, 0x8d,
-  0x4d, 0x82, 0x8a, 0x4a, 0x7f, 0x87, 0x46, 0x7c, 0x84, 0x43, 0x79, 0x82,
-  0x40, 0x76, 0x7f, 0x3c, 0x74, 0x7c, 0x39, 0x71, 0x7a, 0x35, 0x6e, 0x77,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xc8, 0xcc,
+  0x6e, 0x9b, 0xa2, 0x69, 0x97, 0x9e, 0x65, 0x94, 0x9b, 0x61, 0x91, 0x98,
+  0x5d, 0x8e, 0x96, 0x59, 0x8b, 0x93, 0x55, 0x88, 0x90, 0x50, 0x84, 0x8d,
+  0x4d, 0x81, 0x8a, 0x49, 0x7e, 0x86, 0x46, 0x7c, 0x84, 0x42, 0x78, 0x81,
+  0x40, 0x76, 0x7f, 0x3c, 0x74, 0x7c, 0x38, 0x70, 0x79, 0x35, 0x6e, 0x77,
   0x33, 0x6b, 0x74, 0x30, 0x68, 0x72, 0x2e, 0x66, 0x70, 0x2b, 0x64, 0x6d,
   0x28, 0x61, 0x6a, 0x26, 0x60, 0x69, 0x25, 0x5e, 0x67, 0x23, 0x5c, 0x65,
-  0x21, 0x5a, 0x63, 0x1e, 0x57, 0x60, 0x1d, 0x56, 0x5f, 0x1c, 0x54, 0x5e,
+  0x21, 0x5a, 0x63, 0x1f, 0x58, 0x61, 0x1d, 0x56, 0x5f, 0x1b, 0x53, 0x5d,
   0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
-  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
+  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x85, 0x9d, 0xa1, 0x98, 0xac, 0xaf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -7399,1492 +7335,84 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x0f, 0x12, 0x03, 0x12, 0x14,
-  0xc5, 0xcf, 0xd1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x12, 0x00, 0x0c, 0x0e,
+  0x79, 0x8e, 0x91, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed, 0xf3, 0xf4,
-  0x7b, 0xa5, 0xab, 0x6c, 0x99, 0xa0, 0x67, 0x96, 0x9d, 0x64, 0x93, 0x9a,
-  0x5f, 0x8f, 0x97, 0x5a, 0x8c, 0x94, 0x57, 0x89, 0x92, 0x52, 0x85, 0x8e,
-  0x4e, 0x83, 0x8b, 0x4b, 0x7f, 0x88, 0x47, 0x7d, 0x85, 0x44, 0x7a, 0x82,
-  0x41, 0x77, 0x80, 0x3d, 0x74, 0x7c, 0x39, 0x71, 0x7a, 0x36, 0x6f, 0x77,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0xf0, 0xf1, 0x7a, 0xa4, 0xaa,
+  0x70, 0x9c, 0xa3, 0x6b, 0x99, 0xa0, 0x66, 0x95, 0x9c, 0x63, 0x92, 0x9a,
+  0x5f, 0x8f, 0x97, 0x5a, 0x8c, 0x94, 0x56, 0x89, 0x91, 0x52, 0x85, 0x8e,
+  0x4e, 0x83, 0x8b, 0x4b, 0x7f, 0x88, 0x47, 0x7d, 0x85, 0x43, 0x79, 0x82,
+  0x40, 0x76, 0x7f, 0x3d, 0x74, 0x7c, 0x39, 0x71, 0x7a, 0x36, 0x6f, 0x77,
+  0x34, 0x6c, 0x75, 0x31, 0x69, 0x73, 0x2e, 0x66, 0x70, 0x2c, 0x65, 0x6e,
+  0x29, 0x62, 0x6b, 0x26, 0x60, 0x69, 0x25, 0x5e, 0x67, 0x23, 0x5c, 0x65,
+  0x21, 0x5a, 0x63, 0x1f, 0x58, 0x61, 0x1d, 0x56, 0x5f, 0x1c, 0x54, 0x5e,
+  0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
+  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
+  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x23, 0x4e, 0x56, 0x36, 0x5d, 0x64,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0a, 0x0c,
+  0x4a, 0x63, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, 0xca, 0xce, 0x75, 0xa0, 0xa7,
+  0x70, 0x9d, 0xa4, 0x6d, 0x9a, 0xa1, 0x68, 0x96, 0x9d, 0x64, 0x94, 0x9b,
+  0x60, 0x90, 0x98, 0x5b, 0x8d, 0x95, 0x57, 0x89, 0x92, 0x53, 0x86, 0x8f,
+  0x4f, 0x83, 0x8b, 0x4c, 0x80, 0x88, 0x48, 0x7d, 0x86, 0x45, 0x7a, 0x83,
+  0x40, 0x76, 0x7f, 0x3d, 0x74, 0x7c, 0x3a, 0x72, 0x7b, 0x37, 0x6f, 0x78,
   0x34, 0x6c, 0x75, 0x31, 0x69, 0x73, 0x2f, 0x67, 0x70, 0x2c, 0x65, 0x6e,
-  0x29, 0x62, 0x6b, 0x27, 0x60, 0x6a, 0x25, 0x5e, 0x67, 0x23, 0x5c, 0x65,
-  0x20, 0x59, 0x62, 0x1f, 0x58, 0x61, 0x1e, 0x57, 0x60, 0x1c, 0x54, 0x5e,
-  0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
-  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x12, 0x00, 0x0d, 0x0f,
-  0x8e, 0x9f, 0xa2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xc7, 0xcb,
-  0x71, 0x9d, 0xa4, 0x6e, 0x9b, 0xa1, 0x69, 0x97, 0x9e, 0x64, 0x94, 0x9b,
-  0x61, 0x90, 0x98, 0x5b, 0x8d, 0x95, 0x58, 0x8a, 0x92, 0x54, 0x86, 0x8f,
-  0x4f, 0x83, 0x8b, 0x4c, 0x80, 0x88, 0x48, 0x7d, 0x86, 0x44, 0x7a, 0x82,
-  0x41, 0x77, 0x80, 0x3e, 0x75, 0x7d, 0x3a, 0x72, 0x7b, 0x37, 0x6f, 0x78,
-  0x34, 0x6d, 0x75, 0x32, 0x6a, 0x73, 0x2f, 0x67, 0x70, 0x2c, 0x65, 0x6e,
-  0x2a, 0x63, 0x6b, 0x27, 0x60, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x66,
-  0x22, 0x5a, 0x64, 0x20, 0x59, 0x61, 0x1e, 0x57, 0x60, 0x1c, 0x54, 0x5e,
+  0x29, 0x62, 0x6b, 0x28, 0x61, 0x6a, 0x25, 0x5e, 0x67, 0x22, 0x5b, 0x64,
+  0x21, 0x5a, 0x63, 0x20, 0x59, 0x61, 0x1e, 0x57, 0x60, 0x1c, 0x54, 0x5e,
   0x1b, 0x53, 0x5c, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
-  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xc9, 0xd5, 0xd7,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x12, 0x00, 0x0b, 0x0d,
-  0x59, 0x71, 0x75, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0xf0, 0xf1, 0x7e, 0xa6, 0xad,
-  0x73, 0x9e, 0xa6, 0x6f, 0x9b, 0xa2, 0x6a, 0x97, 0x9e, 0x66, 0x95, 0x9c,
-  0x62, 0x91, 0x99, 0x5d, 0x8e, 0x96, 0x59, 0x8a, 0x93, 0x55, 0x87, 0x90,
-  0x50, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x49, 0x7e, 0x86, 0x45, 0x7a, 0x83,
-  0x42, 0x78, 0x80, 0x3f, 0x76, 0x7e, 0x3b, 0x72, 0x7b, 0x38, 0x70, 0x79,
-  0x34, 0x6d, 0x75, 0x32, 0x6a, 0x73, 0x30, 0x68, 0x71, 0x2d, 0x65, 0x6e,
-  0x2a, 0x63, 0x6b, 0x28, 0x61, 0x6a, 0x25, 0x5e, 0x67, 0x24, 0x5d, 0x66,
-  0x22, 0x5a, 0x64, 0x1f, 0x58, 0x61, 0x1e, 0x57, 0x60, 0x1d, 0x55, 0x5e,
-  0x1b, 0x53, 0x5c, 0x19, 0x52, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
-  0x16, 0x4d, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xc9, 0xd5, 0xd7,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0a, 0x0c,
-  0x37, 0x4f, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb4, 0xcc, 0xd0, 0x79, 0xa3, 0xaa,
-  0x74, 0x9f, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0, 0x67, 0x96, 0x9d,
-  0x63, 0x92, 0x9a, 0x5e, 0x8f, 0x97, 0x5a, 0x8b, 0x94, 0x56, 0x88, 0x90,
-  0x51, 0x85, 0x8d, 0x4d, 0x81, 0x89, 0x4a, 0x7f, 0x87, 0x47, 0x7c, 0x84,
-  0x42, 0x78, 0x80, 0x3f, 0x76, 0x7e, 0x3c, 0x73, 0x7c, 0x38, 0x70, 0x79,
-  0x35, 0x6d, 0x76, 0x33, 0x6a, 0x74, 0x30, 0x68, 0x71, 0x2d, 0x65, 0x6e,
-  0x2a, 0x63, 0x6b, 0x28, 0x61, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x66,
-  0x21, 0x5a, 0x63, 0x20, 0x59, 0x61, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
-  0x1b, 0x53, 0x5c, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xc9, 0xd5, 0xd7,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0a, 0x0c,
-  0x23, 0x3a, 0x3d, 0xfb, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xf2, 0xf6, 0xf7, 0x8b, 0xb0, 0xb5, 0x7a, 0xa4, 0xaa,
-  0x75, 0xa0, 0xa7, 0x71, 0x9d, 0xa4, 0x6d, 0x99, 0xa0, 0x68, 0x96, 0x9d,
-  0x64, 0x92, 0x9a, 0x5f, 0x90, 0x97, 0x5a, 0x8c, 0x94, 0x57, 0x88, 0x91,
-  0x52, 0x85, 0x8d, 0x4e, 0x82, 0x8a, 0x4b, 0x7f, 0x88, 0x48, 0x7c, 0x85,
-  0x44, 0x79, 0x82, 0x40, 0x76, 0x7e, 0x3d, 0x74, 0x7c, 0x39, 0x71, 0x79,
-  0x36, 0x6e, 0x76, 0x33, 0x6a, 0x74, 0x31, 0x68, 0x72, 0x2e, 0x66, 0x6f,
-  0x2b, 0x63, 0x6c, 0x29, 0x62, 0x6b, 0x26, 0x5f, 0x68, 0x25, 0x5d, 0x66,
-  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
-  0x1b, 0x53, 0x5c, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xc9, 0xd5, 0xd7,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x6b, 0x9d, 0xa4, 0x86, 0xaf, 0xb5, 0x84, 0xae, 0xb4,
-  0x84, 0xae, 0xb4, 0x84, 0xae, 0xb4, 0x84, 0xae, 0xb4, 0x85, 0xaf, 0xb4,
-  0x7e, 0xaa, 0xb0, 0x1b, 0x69, 0x74, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x32, 0x76, 0x80, 0x68, 0x9a, 0xa1, 0x83, 0xac, 0xb2,
-  0x85, 0xae, 0xb4, 0x77, 0xa5, 0xab, 0x4b, 0x86, 0x8f, 0x0f, 0x5e, 0x69,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x72, 0x9e, 0xa5, 0x98, 0xb9, 0xbd, 0x27, 0x6a, 0x73, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x0f, 0x56, 0x60, 0x36, 0x71, 0x7a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x1c, 0x59, 0x61, 0xa7, 0xbe, 0xc2, 0xa7, 0xbe, 0xc1,
-  0x1c, 0x57, 0x5f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x0a, 0x43, 0x4b, 0x96, 0xae, 0xb1, 0xb3, 0xc4, 0xc7,
-  0x2f, 0x5e, 0x64, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x0d, 0x39, 0x3f,
-  0x74, 0x8c, 0x90, 0x7c, 0x92, 0x95, 0x13, 0x3a, 0x40, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x62, 0x77, 0x79, 0x86, 0x95, 0x97,
-  0x7e, 0x8d, 0x8f, 0x2e, 0x45, 0x49, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0b, 0x0d,
-  0x14, 0x29, 0x2c, 0xe5, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xd1, 0xdf, 0xe2, 0x7f, 0xa8, 0xae, 0x7b, 0xa4, 0xab,
-  0x77, 0xa1, 0xa8, 0x72, 0x9e, 0xa4, 0x6e, 0x9a, 0xa1, 0x69, 0x97, 0x9e,
-  0x65, 0x94, 0x9b, 0x5f, 0x90, 0x97, 0x5b, 0x8c, 0x95, 0x58, 0x89, 0x92,
-  0x53, 0x86, 0x8e, 0x4f, 0x82, 0x8b, 0x4c, 0x80, 0x88, 0x49, 0x7d, 0x86,
-  0x45, 0x7a, 0x82, 0x41, 0x77, 0x7f, 0x3d, 0x74, 0x7c, 0x3a, 0x72, 0x7a,
-  0x36, 0x6e, 0x76, 0x34, 0x6b, 0x75, 0x31, 0x68, 0x72, 0x2e, 0x66, 0x6f,
-  0x2c, 0x64, 0x6d, 0x29, 0x62, 0x6b, 0x26, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
-  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xcc, 0xd7, 0xd9,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xbe, 0xc1,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xd8, 0xe5, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0x33, 0x79, 0x82, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x18, 0x65, 0x70,
-  0x9e, 0xbf, 0xc3, 0xf9, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xdf, 0xe1,
-  0x49, 0x85, 0x8e, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xcf, 0xde, 0xe0, 0xff, 0xff, 0xff, 0x44, 0x7e, 0x86, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0xa6, 0xc0, 0xc4, 0x8e, 0xaf, 0xb4, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x08, 0x4a, 0x53, 0xc5, 0xd4, 0xd7, 0xff, 0xff, 0xff,
-  0x76, 0x99, 0x9e, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x4f, 0x78, 0x7e, 0xff, 0xff, 0xff, 0xe5, 0xeb, 0xec,
-  0x15, 0x49, 0x50, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x17, 0x41, 0x47,
-  0xef, 0xf2, 0xf2, 0xff, 0xff, 0xff, 0x25, 0x49, 0x4e, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x69, 0x7c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0x7f, 0x8e, 0x90, 0x10, 0x2a, 0x2f, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0d, 0x0f,
-  0x0a, 0x1c, 0x1f, 0xcc, 0xd1, 0xd2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xaa, 0xc5, 0xc9, 0x81, 0xa9, 0xaf, 0x7d, 0xa5, 0xac,
-  0x78, 0xa2, 0xa9, 0x73, 0x9e, 0xa5, 0x6f, 0x9b, 0xa1, 0x6a, 0x97, 0x9e,
-  0x66, 0x94, 0x9c, 0x61, 0x91, 0x98, 0x5c, 0x8d, 0x95, 0x58, 0x89, 0x92,
-  0x54, 0x86, 0x8e, 0x50, 0x83, 0x8b, 0x4c, 0x80, 0x88, 0x49, 0x7d, 0x86,
-  0x44, 0x79, 0x82, 0x41, 0x77, 0x7f, 0x3e, 0x74, 0x7d, 0x3a, 0x72, 0x7a,
-  0x37, 0x6f, 0x77, 0x34, 0x6b, 0x75, 0x31, 0x68, 0x72, 0x2f, 0x67, 0x70,
-  0x2c, 0x64, 0x6d, 0x29, 0x62, 0x6b, 0x26, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1e, 0x56, 0x5f,
-  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x34, 0x60, 0x67,
-  0x3f, 0x68, 0x6e, 0x3b, 0x65, 0x6b, 0x3b, 0x64, 0x6a, 0x3b, 0x63, 0x6a,
-  0x3b, 0x63, 0x69, 0x3b, 0x62, 0x68, 0x3b, 0x62, 0x68, 0x2b, 0x54, 0x5b,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xcd, 0xde, 0xe1, 0xff, 0xff, 0xff, 0x97, 0xbb, 0xc0,
-  0x7b, 0xa8, 0xaf, 0x7d, 0xa9, 0xb0, 0x7d, 0xa9, 0xb0, 0x7e, 0xaa, 0xb0,
-  0x77, 0xa6, 0xac, 0x1a, 0x68, 0x73, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x11, 0x61, 0x6d, 0xc1, 0xd5, 0xd8,
-  0xff, 0xff, 0xff, 0xf4, 0xf8, 0xf8, 0xa7, 0xc4, 0xc9, 0x80, 0xaa, 0xb0,
-  0x7b, 0xa7, 0xad, 0x92, 0xb6, 0xbb, 0xd4, 0xe2, 0xe4, 0xff, 0xff, 0xff,
-  0xf8, 0xfa, 0xfb, 0x4b, 0x86, 0x8e, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x85, 0xaa, 0xaf,
-  0xff, 0xff, 0xff, 0x85, 0xa9, 0xae, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x5a, 0x86, 0x8c, 0xff, 0xff, 0xff,
-  0xd4, 0xdf, 0xe1, 0x0c, 0x4a, 0x53, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0xb4, 0xc5, 0xc8, 0xff, 0xff, 0xff, 0x7b, 0x99, 0x9d,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x45, 0x5e, 0x62, 0xf8, 0xf9, 0xf9, 0xff, 0xff, 0xff, 0x8d, 0x9b, 0x9d,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0d, 0x10,
-  0x03, 0x12, 0x15, 0xb8, 0xbf, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xf4, 0xf8, 0xf8, 0x93, 0xb5, 0xba, 0x81, 0xa9, 0xaf, 0x7d, 0xa5, 0xac,
-  0x78, 0xa2, 0xa9, 0x73, 0x9e, 0xa5, 0x70, 0x9b, 0xa2, 0x6b, 0x98, 0x9f,
-  0x66, 0x94, 0x9c, 0x61, 0x91, 0x98, 0x5d, 0x8e, 0x96, 0x59, 0x8a, 0x92,
-  0x55, 0x87, 0x8f, 0x50, 0x83, 0x8b, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
-  0x46, 0x7a, 0x83, 0x42, 0x78, 0x80, 0x3e, 0x74, 0x7d, 0x3a, 0x72, 0x7a,
-  0x37, 0x6f, 0x77, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
-  0x2c, 0x64, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x2e, 0x75, 0x7f,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x82, 0xac, 0xb2, 0xff, 0xff, 0xff,
-  0xd9, 0xe6, 0xe7, 0x35, 0x78, 0x82, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x0f, 0x5e, 0x69, 0x93, 0xb6, 0xbc,
-  0xff, 0xff, 0xff, 0xdf, 0xe9, 0xeb, 0x16, 0x62, 0x6d, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x74, 0x9e, 0xa4, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x10, 0x4f, 0x59, 0xdf, 0xe7, 0xe8,
-  0xff, 0xff, 0xff, 0x4e, 0x7b, 0x81, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x31, 0x62, 0x69, 0xf9, 0xfa, 0xfb, 0xf1, 0xf4, 0xf5, 0x22, 0x54, 0x5b,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x2c, 0x4a, 0x4e,
-  0xe6, 0xea, 0xea, 0xff, 0xff, 0xff, 0xa8, 0xb3, 0xb4, 0x04, 0x23, 0x28,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
-  0x01, 0x0d, 0x0f, 0xa6, 0xb1, 0xb2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xe1, 0xeb, 0xec, 0x87, 0xad, 0xb3, 0x82, 0xaa, 0xb0, 0x7d, 0xa6, 0xad,
-  0x79, 0xa2, 0xa9, 0x74, 0x9f, 0xa6, 0x70, 0x9b, 0xa2, 0x6b, 0x98, 0x9f,
-  0x66, 0x94, 0x9c, 0x62, 0x92, 0x99, 0x5d, 0x8e, 0x96, 0x5a, 0x8a, 0x93,
-  0x55, 0x87, 0x8f, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
-  0x46, 0x7a, 0x83, 0x42, 0x78, 0x80, 0x3e, 0x74, 0x7d, 0x3b, 0x72, 0x7a,
-  0x37, 0x6f, 0x77, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
-  0x2c, 0x64, 0x6d, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x26, 0x5e, 0x67,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1c, 0x54, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x12, 0x62, 0x6d, 0xe1, 0xeb, 0xec, 0xfc, 0xfd, 0xfd,
-  0x47, 0x85, 0x8d, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x07, 0x59, 0x65,
-  0xc7, 0xda, 0xdc, 0xff, 0xff, 0xff, 0x5f, 0x94, 0x9b, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x63, 0x93, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x83, 0xa4, 0xa9,
-  0xff, 0xff, 0xff, 0xb0, 0xc4, 0xc7, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x92, 0xab, 0xaf, 0xff, 0xff, 0xff, 0xa1, 0xb7, 0xba, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x15, 0x37, 0x3d, 0xcf, 0xd5, 0xd6,
-  0xff, 0xff, 0xff, 0xc1, 0xc9, 0xca, 0x0d, 0x2c, 0x30, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
-  0x01, 0x0c, 0x0e, 0x90, 0x9d, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xcc, 0xdd, 0xdf, 0x88, 0xae, 0xb4, 0x83, 0xaa, 0xb0, 0x7e, 0xa7, 0xad,
-  0x7a, 0xa3, 0xaa, 0x75, 0xa0, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0,
-  0x67, 0x95, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8a, 0x93,
-  0x56, 0x88, 0x90, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
-  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
-  0x38, 0x6f, 0x78, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x26, 0x5e, 0x67,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1c, 0x54, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x29, 0x71, 0x7c, 0xff, 0xff, 0xff, 0xe0, 0xea, 0xec,
-  0x0a, 0x5c, 0x67, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x7b, 0xa7, 0xad, 0xff, 0xff, 0xff, 0x8d, 0xb2, 0xb7, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x54, 0x88, 0x90, 0xfa, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xdb, 0xe6, 0xe7,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x2a, 0x62, 0x6a,
-  0xf6, 0xf8, 0xf9, 0xf9, 0xfb, 0xfb, 0x2c, 0x61, 0x69, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x1b, 0x51, 0x59,
-  0xe9, 0xee, 0xef, 0xfd, 0xfd, 0xfe, 0x3e, 0x6b, 0x71, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x07, 0x2c, 0x32, 0xb1, 0xbc, 0xbe, 0xff, 0xff, 0xff,
-  0xd5, 0xdb, 0xdc, 0x1d, 0x3a, 0x3f, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
-  0x00, 0x0b, 0x0d, 0x7d, 0x8c, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xb8, 0xcf, 0xd3, 0x88, 0xae, 0xb4, 0x83, 0xaa, 0xb0, 0x7e, 0xa7, 0xad,
-  0x7a, 0xa3, 0xaa, 0x75, 0xa0, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0,
-  0x67, 0x95, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8b, 0x93,
-  0x56, 0x88, 0x90, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
-  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
-  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x32, 0x69, 0x72, 0x30, 0x68, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x26, 0x5e, 0x67,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2f, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd5, 0xe3, 0xe5,
-  0x0a, 0x5c, 0x67, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x72, 0xa1, 0xa7, 0xff, 0xff, 0xff, 0x91, 0xb5, 0xba, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x47, 0x7f, 0x87,
-  0xf5, 0xf8, 0xf9, 0xff, 0xff, 0xff, 0x7b, 0xa2, 0xa8, 0x78, 0xa0, 0xa6,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0xaf, 0xc4, 0xc6, 0xff, 0xff, 0xff, 0x88, 0xa6, 0xab, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x6e, 0x91, 0x96,
-  0xff, 0xff, 0xff, 0xc5, 0xd2, 0xd4, 0x06, 0x40, 0x47, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x8e, 0x9f, 0xa2, 0xff, 0xff, 0xff, 0xdb, 0xe1, 0xe1,
-  0x26, 0x43, 0x47, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
-  0x00, 0x0b, 0x0d, 0x6e, 0x7f, 0x82, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xa9, 0xc5, 0xc9, 0x89, 0xae, 0xb4, 0x84, 0xab, 0xb1, 0x7f, 0xa7, 0xae,
-  0x7b, 0xa4, 0xaa, 0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa3, 0x6d, 0x99, 0xa0,
-  0x68, 0x96, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8b, 0x93,
-  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
-  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
-  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x33, 0x6a, 0x73, 0x30, 0x68, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x3a, 0x77, 0x7f, 0xec, 0xf2, 0xf3,
-  0xff, 0xff, 0xff, 0x9f, 0xbc, 0xc0, 0x05, 0x50, 0x5b, 0x7b, 0xa2, 0xa8,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x4f, 0x7c, 0x83, 0xff, 0xff, 0xff, 0xe2, 0xe9, 0xea, 0x14, 0x4e, 0x57,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x0a, 0x45, 0x4e, 0xd2, 0xdd, 0xde,
-  0xff, 0xff, 0xff, 0x62, 0x87, 0x8c, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x22, 0x47, 0x4c, 0x03, 0x2c, 0x32,
-  0x6a, 0x81, 0x84, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa4, 0xb1, 0xb3,
-  0x27, 0x44, 0x48, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
-  0x00, 0x0b, 0x0c, 0x66, 0x77, 0x7a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xa2, 0xc0, 0xc4, 0x89, 0xae, 0xb4, 0x84, 0xab, 0xb1, 0x7f, 0xa7, 0xae,
-  0x7b, 0xa4, 0xaa, 0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa3, 0x6d, 0x99, 0xa0,
-  0x68, 0x96, 0x9d, 0x63, 0x92, 0x9a, 0x5f, 0x8f, 0x97, 0x5a, 0x8b, 0x93,
-  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
-  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3c, 0x73, 0x7b,
-  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x33, 0x6a, 0x73, 0x30, 0x68, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x2f, 0x6f, 0x78, 0xe4, 0xec, 0xed, 0xff, 0xff, 0xff,
-  0xb3, 0xca, 0xcd, 0x0b, 0x55, 0x5f, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x0c, 0x4b, 0x54, 0xd6, 0xe0, 0xe2, 0xff, 0xff, 0xff, 0x61, 0x88, 0x8f,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x4f, 0x7a, 0x80, 0xff, 0xff, 0xff,
-  0xe1, 0xe8, 0xe9, 0x14, 0x4a, 0x53, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x19, 0x3f, 0x45, 0x4e, 0x6b, 0x6f,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xfe, 0xfe, 0xfe, 0x9e, 0xab, 0xad, 0x17, 0x35, 0x39, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
-  0x00, 0x0a, 0x0c, 0x61, 0x73, 0x76, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfc,
-  0x9e, 0xbd, 0xc2, 0x89, 0xae, 0xb4, 0x84, 0xab, 0xb1, 0x7f, 0xa7, 0xae,
-  0x7b, 0xa4, 0xaa, 0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa3, 0x6d, 0x99, 0xa0,
-  0x68, 0x96, 0x9d, 0x64, 0x93, 0x9a, 0x5f, 0x8f, 0x97, 0x5a, 0x8b, 0x93,
-  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
-  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3c, 0x73, 0x7b,
-  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x33, 0x6a, 0x73, 0x30, 0x68, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x43, 0x7d, 0x85, 0x06, 0x53, 0x5e,
-  0x23, 0x68, 0x72, 0xd8, 0xe4, 0xe6, 0xff, 0xff, 0xff, 0xc3, 0xd5, 0xd8,
-  0x11, 0x59, 0x64, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x78, 0x9a, 0x9f, 0xff, 0xff, 0xff, 0xc2, 0xd1, 0xd4,
-  0x05, 0x44, 0x4d, 0x04, 0x42, 0x4b, 0xb4, 0xc6, 0xc9, 0xff, 0xff, 0xff,
-  0x89, 0xa5, 0xa9, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x20, 0x45, 0x4a, 0x33, 0x55, 0x59,
-  0x47, 0x64, 0x68, 0x46, 0x62, 0x66, 0x55, 0x6e, 0x72, 0x84, 0x96, 0x98,
-  0xdb, 0xe0, 0xe1, 0xff, 0xff, 0xff, 0xcd, 0xd4, 0xd5, 0x18, 0x34, 0x39,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
-  0x00, 0x0a, 0x0c, 0x61, 0x73, 0x76, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfb, 0xfb,
-  0x9c, 0xbc, 0xc1, 0x89, 0xae, 0xb4, 0x84, 0xab, 0xb1, 0x7f, 0xa7, 0xae,
-  0x7b, 0xa4, 0xaa, 0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa3, 0x6d, 0x99, 0xa0,
-  0x68, 0x96, 0x9d, 0x63, 0x92, 0x9a, 0x5f, 0x8f, 0x97, 0x5a, 0x8b, 0x93,
-  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
-  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3c, 0x73, 0x7b,
-  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x33, 0x6a, 0x73, 0x30, 0x68, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x38, 0x75, 0x7e, 0x12, 0x5b, 0x66,
-  0xcb, 0xdb, 0xde, 0xff, 0xff, 0xff, 0xd2, 0xe0, 0xe2, 0x1d, 0x61, 0x6b,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x21, 0x5a, 0x62, 0xf1, 0xf5, 0xf5, 0xfe, 0xfe, 0xfe,
-  0x32, 0x66, 0x6d, 0x26, 0x5c, 0x64, 0xf9, 0xfb, 0xfb, 0xf7, 0xf9, 0xf9,
-  0x29, 0x5c, 0x63, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x12, 0x32, 0x37, 0xb9, 0xc2, 0xc3, 0xff, 0xff, 0xff, 0x89, 0x97, 0x9a,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
-  0x00, 0x0a, 0x0c, 0x64, 0x75, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xfc, 0xfc,
-  0x9d, 0xbc, 0xc1, 0x89, 0xae, 0xb4, 0x83, 0xaa, 0xb0, 0x7e, 0xa7, 0xad,
-  0x7a, 0xa3, 0xaa, 0x75, 0xa0, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0,
-  0x68, 0x96, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8b, 0x93,
-  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
-  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
-  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x32, 0x69, 0x72, 0x30, 0x68, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x26, 0x5e, 0x67,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x4b, 0x83, 0x8b, 0xb4, 0xcb, 0xce,
-  0xff, 0xff, 0xff, 0xe0, 0xe9, 0xeb, 0x2a, 0x6c, 0x75, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0xa3, 0xba, 0xbd, 0xff, 0xff, 0xff,
-  0x94, 0xaf, 0xb2, 0x89, 0xa6, 0xaa, 0xff, 0xff, 0xff, 0xae, 0xc2, 0xc4,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x3a, 0x54, 0x58, 0xff, 0xff, 0xff, 0xd1, 0xd7, 0xd8,
-  0x06, 0x23, 0x27, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
-  0x00, 0x0b, 0x0d, 0x6b, 0x7c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xa0, 0xbf, 0xc4, 0x88, 0xae, 0xb4, 0x83, 0xaa, 0xb0, 0x7e, 0xa7, 0xad,
-  0x7a, 0xa3, 0xaa, 0x75, 0xa0, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0,
-  0x67, 0x95, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8a, 0x93,
-  0x56, 0x88, 0x90, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
-  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
-  0x38, 0x6f, 0x78, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x26, 0x5e, 0x67,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc4, 0xd7, 0xd9, 0xff, 0xff, 0xff, 0xdc, 0xe7, 0xe8, 0xff, 0xff, 0xff,
-  0xec, 0xf2, 0xf3, 0x3a, 0x77, 0x7f, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x44, 0x73, 0x7a, 0xfe, 0xfe, 0xfe,
-  0xf2, 0xf5, 0xf6, 0xf5, 0xf8, 0xf8, 0xff, 0xff, 0xff, 0x4a, 0x75, 0x7c,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x1b, 0x39, 0x3d, 0xfe, 0xfe, 0xfe, 0xe5, 0xe8, 0xe9,
-  0x0a, 0x27, 0x2b, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
-  0x00, 0x0b, 0x0d, 0x78, 0x87, 0x8a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xa6, 0xc3, 0xc7, 0x87, 0xad, 0xb3, 0x82, 0xaa, 0xb0, 0x7d, 0xa6, 0xad,
-  0x79, 0xa2, 0xa9, 0x74, 0x9f, 0xa6, 0x70, 0x9b, 0xa2, 0x6c, 0x99, 0xa0,
-  0x67, 0x95, 0x9d, 0x62, 0x92, 0x99, 0x5e, 0x8e, 0x97, 0x5a, 0x8a, 0x93,
-  0x55, 0x87, 0x8f, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
-  0x45, 0x7a, 0x82, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
-  0x38, 0x6f, 0x78, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
-  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x26, 0x5e, 0x67,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1c, 0x54, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc4, 0xd7, 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf9, 0xf9,
-  0x4a, 0x82, 0x8a, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x08, 0x46, 0x4f, 0xcb, 0xd8, 0xda,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xda, 0xdc, 0x0a, 0x44, 0x4d,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x3c, 0x56, 0x5a, 0xff, 0xff, 0xff, 0xd1, 0xd7, 0xd8,
-  0x06, 0x23, 0x27, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
-  0x01, 0x0c, 0x0e, 0x88, 0x95, 0x97, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xb4, 0xcd, 0xd0, 0x87, 0xad, 0xb3, 0x82, 0xaa, 0xb0, 0x7d, 0xa6, 0xad,
-  0x79, 0xa2, 0xa9, 0x74, 0x9f, 0xa6, 0x70, 0x9b, 0xa2, 0x6b, 0x98, 0x9f,
-  0x66, 0x94, 0x9c, 0x62, 0x92, 0x99, 0x5d, 0x8e, 0x96, 0x59, 0x8a, 0x92,
-  0x55, 0x87, 0x8f, 0x50, 0x83, 0x8b, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
-  0x46, 0x7a, 0x83, 0x42, 0x78, 0x80, 0x3e, 0x74, 0x7d, 0x3b, 0x72, 0x7a,
-  0x37, 0x6f, 0x77, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
-  0x2c, 0x64, 0x6d, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x26, 0x5e, 0x67,
-  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
-  0x1c, 0x54, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc4, 0xd7, 0xd9, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xfe, 0x5b, 0x8e, 0x95,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x6c, 0x90, 0x96,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x92, 0x97, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe3, 0xe8, 0xe9, 0xf1, 0xf4, 0xf4, 0x19, 0x3f, 0x45, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x0a, 0x2b, 0x30, 0xb3, 0xbd, 0xbe, 0xff, 0xff, 0xff, 0x91, 0x9e, 0xa1,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
-  0x01, 0x0c, 0x0e, 0xa0, 0xab, 0xac, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xc8, 0xda, 0xdd, 0x86, 0xac, 0xb2, 0x81, 0xa9, 0xaf, 0x7d, 0xa5, 0xac,
-  0x78, 0xa2, 0xa9, 0x73, 0x9e, 0xa5, 0x6f, 0x9b, 0xa1, 0x6a, 0x97, 0x9e,
-  0x65, 0x94, 0x9b, 0x61, 0x91, 0x98, 0x5c, 0x8d, 0x95, 0x59, 0x8a, 0x92,
-  0x54, 0x86, 0x8e, 0x50, 0x83, 0x8b, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
-  0x46, 0x7a, 0x83, 0x42, 0x78, 0x80, 0x3e, 0x74, 0x7d, 0x3a, 0x72, 0x7a,
-  0x37, 0x6f, 0x77, 0x34, 0x6c, 0x75, 0x31, 0x68, 0x72, 0x2f, 0x67, 0x70,
-  0x2c, 0x64, 0x6d, 0x29, 0x62, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x22, 0x5a, 0x64, 0x20, 0x59, 0x61, 0x1f, 0x57, 0x61, 0x1e, 0x56, 0x5f,
-  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xc7, 0xd9, 0xdb, 0xff, 0xff, 0xff, 0x6e, 0x9a, 0xa1, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
-  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x1b, 0x53, 0x5c,
-  0xee, 0xf2, 0xf3, 0xee, 0xf2, 0xf3, 0x1a, 0x51, 0x5a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
-  0xe1, 0xe7, 0xe7, 0xf7, 0xf8, 0xf9, 0x66, 0x7f, 0x83, 0x4d, 0x6a, 0x6e,
-  0x50, 0x6b, 0x6f, 0x4f, 0x6a, 0x6e, 0x4f, 0x69, 0x6d, 0x74, 0x88, 0x8a,
-  0xcc, 0xd3, 0xd4, 0xff, 0xff, 0xff, 0xe7, 0xea, 0xeb, 0x25, 0x3f, 0x44,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0d, 0x10,
-  0x03, 0x10, 0x12, 0xb3, 0xbb, 0xbc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xde, 0xe9, 0xea, 0x85, 0xac, 0xb2, 0x80, 0xa9, 0xae, 0x7c, 0xa5, 0xab,
-  0x77, 0xa1, 0xa8, 0x72, 0x9e, 0xa4, 0x6e, 0x9a, 0xa1, 0x69, 0x97, 0x9e,
-  0x65, 0x94, 0x9b, 0x60, 0x90, 0x98, 0x5c, 0x8d, 0x95, 0x58, 0x89, 0x92,
-  0x54, 0x86, 0x8e, 0x4f, 0x82, 0x8b, 0x4c, 0x80, 0x88, 0x49, 0x7d, 0x86,
-  0x45, 0x7a, 0x82, 0x41, 0x77, 0x7f, 0x3d, 0x74, 0x7c, 0x3a, 0x72, 0x7a,
-  0x36, 0x6e, 0x76, 0x34, 0x6b, 0x75, 0x31, 0x68, 0x72, 0x2e, 0x66, 0x6f,
-  0x2b, 0x63, 0x6c, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x24, 0x5d, 0x66,
-  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
-  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0xd7, 0xe5, 0xe7, 0xff, 0xff, 0xff, 0x3b, 0x7e, 0x87,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x30, 0x76, 0x80, 0xff, 0xff, 0xff, 0xe0, 0xea, 0xec,
-  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x79, 0xa5, 0xac, 0xff, 0xff, 0xff, 0x96, 0xb8, 0xbd, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0xd0, 0xdf, 0xe1, 0x8e, 0xb1, 0xb6, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x84, 0xa9, 0xae,
-  0xff, 0xff, 0xff, 0x8a, 0xac, 0xb2, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0xa2, 0xba, 0xbd, 0xa4, 0xbb, 0xbe, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x17, 0x41, 0x47,
-  0xe7, 0xeb, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xd1, 0xd7, 0xd8, 0x3a, 0x53, 0x56, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0d, 0x0f,
-  0x07, 0x18, 0x1c, 0xc5, 0xcc, 0xcd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xf2, 0xf6, 0xf7, 0x90, 0xb3, 0xb8, 0x7f, 0xa8, 0xae, 0x7b, 0xa4, 0xab,
-  0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa4, 0x6d, 0x99, 0xa0, 0x68, 0x96, 0x9d,
-  0x64, 0x93, 0x9b, 0x5f, 0x90, 0x97, 0x5b, 0x8c, 0x95, 0x57, 0x88, 0x91,
-  0x53, 0x86, 0x8e, 0x4e, 0x82, 0x8a, 0x4b, 0x7f, 0x88, 0x48, 0x7c, 0x85,
-  0x43, 0x78, 0x81, 0x40, 0x76, 0x7e, 0x3d, 0x74, 0x7c, 0x39, 0x71, 0x79,
-  0x36, 0x6e, 0x76, 0x34, 0x6b, 0x75, 0x31, 0x68, 0x72, 0x2e, 0x66, 0x6f,
-  0x2b, 0x63, 0x6c, 0x29, 0x62, 0x6b, 0x26, 0x5f, 0x68, 0x25, 0x5d, 0x66,
-  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
-  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x8e, 0xb4, 0xba, 0xb4, 0xcd, 0xd1, 0x28, 0x72, 0x7c,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x21, 0x6c, 0x77, 0xb1, 0xcb, 0xcf, 0x94, 0xb7, 0xbd,
-  0x09, 0x5b, 0x67, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x51, 0x8a, 0x93, 0xbb, 0xd1, 0xd4, 0x64, 0x97, 0x9e, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x5d, 0x90, 0x97, 0x0a, 0x57, 0x62, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x44, 0x7c, 0x83,
-  0x8c, 0xae, 0xb3, 0x48, 0x7d, 0x85, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x36, 0x69, 0x70, 0x30, 0x63, 0x6b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x10, 0x3c, 0x41,
-  0x97, 0xa9, 0xac, 0xb0, 0xbd, 0xbf, 0xaf, 0xbc, 0xbe, 0xaf, 0xbc, 0xbe,
-  0xaf, 0xbb, 0xbd, 0xaf, 0xbb, 0xbd, 0xb0, 0xbc, 0xbd, 0x98, 0xa7, 0xa9,
-  0x5c, 0x72, 0x75, 0x11, 0x30, 0x35, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0b, 0x0d,
-  0x10, 0x24, 0x27, 0xdc, 0xdf, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xa5, 0xc2, 0xc6, 0x7d, 0xa7, 0xad, 0x79, 0xa3, 0xaa,
-  0x75, 0xa0, 0xa7, 0x70, 0x9d, 0xa3, 0x6c, 0x99, 0xa0, 0x67, 0x96, 0x9d,
-  0x64, 0x92, 0x9a, 0x5e, 0x8f, 0x97, 0x5a, 0x8c, 0x94, 0x56, 0x88, 0x90,
-  0x52, 0x85, 0x8d, 0x4e, 0x82, 0x8a, 0x4b, 0x7f, 0x88, 0x48, 0x7c, 0x85,
-  0x44, 0x79, 0x82, 0x40, 0x76, 0x7e, 0x3c, 0x73, 0x7c, 0x39, 0x71, 0x79,
-  0x35, 0x6d, 0x76, 0x33, 0x6a, 0x74, 0x30, 0x68, 0x71, 0x2e, 0x66, 0x6f,
-  0x2b, 0x63, 0x6c, 0x28, 0x61, 0x6a, 0x26, 0x60, 0x69, 0x25, 0x5d, 0x66,
-  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
-  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0a, 0x0c,
-  0x1d, 0x34, 0x37, 0xf5, 0xf6, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xcd, 0xdd, 0xe0, 0x7d, 0xa6, 0xac, 0x78, 0xa2, 0xa9,
-  0x73, 0x9e, 0xa6, 0x70, 0x9c, 0xa3, 0x6b, 0x98, 0x9f, 0x66, 0x95, 0x9c,
-  0x63, 0x92, 0x9a, 0x5d, 0x8e, 0x96, 0x5a, 0x8b, 0x94, 0x55, 0x87, 0x90,
-  0x51, 0x85, 0x8d, 0x4d, 0x81, 0x89, 0x4a, 0x7f, 0x87, 0x47, 0x7c, 0x84,
-  0x43, 0x78, 0x81, 0x3f, 0x76, 0x7e, 0x3b, 0x72, 0x7b, 0x38, 0x70, 0x79,
-  0x35, 0x6d, 0x76, 0x33, 0x6a, 0x74, 0x30, 0x68, 0x71, 0x2d, 0x65, 0x6e,
-  0x2a, 0x63, 0x6b, 0x28, 0x61, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x66,
-  0x22, 0x5a, 0x64, 0x20, 0x59, 0x61, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
-  0x1b, 0x53, 0x5c, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
-  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
   0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -9000,19 +7528,19 @@
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
   0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0a, 0x0c,
-  0x4a, 0x63, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x1d, 0x34, 0x37, 0xf5, 0xf6, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, 0xca, 0xce, 0x75, 0xa0, 0xa7,
-  0x70, 0x9d, 0xa4, 0x6d, 0x9a, 0xa1, 0x68, 0x96, 0x9d, 0x64, 0x94, 0x9b,
-  0x60, 0x90, 0x98, 0x5b, 0x8d, 0x95, 0x57, 0x89, 0x92, 0x53, 0x86, 0x8f,
-  0x4f, 0x83, 0x8b, 0x4c, 0x80, 0x88, 0x48, 0x7d, 0x86, 0x45, 0x7a, 0x83,
-  0x40, 0x76, 0x7f, 0x3d, 0x74, 0x7c, 0x3a, 0x72, 0x7b, 0x37, 0x6f, 0x78,
-  0x34, 0x6c, 0x75, 0x31, 0x69, 0x73, 0x2f, 0x67, 0x70, 0x2c, 0x65, 0x6e,
-  0x29, 0x62, 0x6b, 0x28, 0x61, 0x6a, 0x25, 0x5e, 0x67, 0x22, 0x5b, 0x64,
-  0x21, 0x5a, 0x63, 0x20, 0x59, 0x61, 0x1e, 0x57, 0x60, 0x1c, 0x54, 0x5e,
-  0x1b, 0x53, 0x5c, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
-  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0xff, 0xff, 0xff, 0xcd, 0xdd, 0xe0, 0x7d, 0xa6, 0xac, 0x78, 0xa2, 0xa9,
+  0x73, 0x9e, 0xa6, 0x70, 0x9c, 0xa3, 0x6b, 0x98, 0x9f, 0x66, 0x95, 0x9c,
+  0x63, 0x92, 0x9a, 0x5d, 0x8e, 0x96, 0x5a, 0x8b, 0x94, 0x55, 0x87, 0x90,
+  0x51, 0x85, 0x8d, 0x4d, 0x81, 0x89, 0x4a, 0x7f, 0x87, 0x47, 0x7c, 0x84,
+  0x43, 0x78, 0x81, 0x3f, 0x76, 0x7e, 0x3b, 0x72, 0x7b, 0x38, 0x70, 0x79,
+  0x35, 0x6d, 0x76, 0x33, 0x6a, 0x74, 0x30, 0x68, 0x71, 0x2d, 0x65, 0x6e,
+  0x2a, 0x63, 0x6b, 0x28, 0x61, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x66,
+  0x22, 0x5a, 0x64, 0x20, 0x59, 0x61, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
+  0x1b, 0x53, 0x5c, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
   0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -9033,6 +7561,1158 @@
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x8e, 0xb4, 0xba, 0xb4, 0xcd, 0xd1, 0x28, 0x72, 0x7c,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x21, 0x6c, 0x77, 0xb1, 0xcb, 0xcf, 0x94, 0xb7, 0xbd,
+  0x09, 0x5b, 0x67, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x51, 0x8a, 0x93, 0xbb, 0xd1, 0xd4, 0x64, 0x97, 0x9e, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x5d, 0x90, 0x97, 0x0a, 0x57, 0x62, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x44, 0x7c, 0x83,
+  0x8c, 0xae, 0xb3, 0x48, 0x7d, 0x85, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x36, 0x69, 0x70, 0x30, 0x63, 0x6b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x10, 0x3c, 0x41,
+  0x97, 0xa9, 0xac, 0xb0, 0xbd, 0xbf, 0xaf, 0xbc, 0xbe, 0xaf, 0xbc, 0xbe,
+  0xaf, 0xbb, 0xbd, 0xaf, 0xbb, 0xbd, 0xb0, 0xbc, 0xbd, 0x98, 0xa7, 0xa9,
+  0x5c, 0x72, 0x75, 0x11, 0x30, 0x35, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0b, 0x0d,
+  0x10, 0x24, 0x27, 0xdc, 0xdf, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xa5, 0xc2, 0xc6, 0x7d, 0xa7, 0xad, 0x79, 0xa3, 0xaa,
+  0x75, 0xa0, 0xa7, 0x70, 0x9d, 0xa3, 0x6c, 0x99, 0xa0, 0x67, 0x96, 0x9d,
+  0x64, 0x92, 0x9a, 0x5e, 0x8f, 0x97, 0x5a, 0x8c, 0x94, 0x56, 0x88, 0x90,
+  0x52, 0x85, 0x8d, 0x4e, 0x82, 0x8a, 0x4b, 0x7f, 0x88, 0x48, 0x7c, 0x85,
+  0x44, 0x79, 0x82, 0x40, 0x76, 0x7e, 0x3c, 0x73, 0x7c, 0x39, 0x71, 0x79,
+  0x35, 0x6d, 0x76, 0x33, 0x6a, 0x74, 0x30, 0x68, 0x71, 0x2e, 0x66, 0x6f,
+  0x2b, 0x63, 0x6c, 0x28, 0x61, 0x6a, 0x26, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
+  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xd7, 0xe5, 0xe7, 0xff, 0xff, 0xff, 0x3b, 0x7e, 0x87,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x30, 0x76, 0x80, 0xff, 0xff, 0xff, 0xe0, 0xea, 0xec,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x79, 0xa5, 0xac, 0xff, 0xff, 0xff, 0x96, 0xb8, 0xbd, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xd0, 0xdf, 0xe1, 0x8e, 0xb1, 0xb6, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x84, 0xa9, 0xae,
+  0xff, 0xff, 0xff, 0x8a, 0xac, 0xb2, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0xa2, 0xba, 0xbd, 0xa4, 0xbb, 0xbe, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x17, 0x41, 0x47,
+  0xe7, 0xeb, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xd1, 0xd7, 0xd8, 0x3a, 0x53, 0x56, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0d, 0x0f,
+  0x07, 0x18, 0x1c, 0xc5, 0xcc, 0xcd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xf2, 0xf6, 0xf7, 0x90, 0xb3, 0xb8, 0x7f, 0xa8, 0xae, 0x7b, 0xa4, 0xab,
+  0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa4, 0x6d, 0x99, 0xa0, 0x68, 0x96, 0x9d,
+  0x64, 0x93, 0x9b, 0x5f, 0x90, 0x97, 0x5b, 0x8c, 0x95, 0x57, 0x88, 0x91,
+  0x53, 0x86, 0x8e, 0x4e, 0x82, 0x8a, 0x4b, 0x7f, 0x88, 0x48, 0x7c, 0x85,
+  0x43, 0x78, 0x81, 0x40, 0x76, 0x7e, 0x3d, 0x74, 0x7c, 0x39, 0x71, 0x79,
+  0x36, 0x6e, 0x76, 0x34, 0x6b, 0x75, 0x31, 0x68, 0x72, 0x2e, 0x66, 0x6f,
+  0x2b, 0x63, 0x6c, 0x29, 0x62, 0x6b, 0x26, 0x5f, 0x68, 0x25, 0x5d, 0x66,
+  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
+  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc7, 0xd9, 0xdb, 0xff, 0xff, 0xff, 0x6e, 0x9a, 0xa1, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x1b, 0x53, 0x5c,
+  0xee, 0xf2, 0xf3, 0xee, 0xf2, 0xf3, 0x1a, 0x51, 0x5a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe1, 0xe7, 0xe7, 0xf7, 0xf8, 0xf9, 0x66, 0x7f, 0x83, 0x4d, 0x6a, 0x6e,
+  0x50, 0x6b, 0x6f, 0x4f, 0x6a, 0x6e, 0x4f, 0x69, 0x6d, 0x74, 0x88, 0x8a,
+  0xcc, 0xd3, 0xd4, 0xff, 0xff, 0xff, 0xe7, 0xea, 0xeb, 0x25, 0x3f, 0x44,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0d, 0x10,
+  0x03, 0x10, 0x12, 0xb3, 0xbb, 0xbc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xde, 0xe9, 0xea, 0x85, 0xac, 0xb2, 0x80, 0xa9, 0xae, 0x7c, 0xa5, 0xab,
+  0x77, 0xa1, 0xa8, 0x72, 0x9e, 0xa4, 0x6e, 0x9a, 0xa1, 0x69, 0x97, 0x9e,
+  0x65, 0x94, 0x9b, 0x60, 0x90, 0x98, 0x5c, 0x8d, 0x95, 0x58, 0x89, 0x92,
+  0x54, 0x86, 0x8e, 0x4f, 0x82, 0x8b, 0x4c, 0x80, 0x88, 0x49, 0x7d, 0x86,
+  0x45, 0x7a, 0x82, 0x41, 0x77, 0x7f, 0x3d, 0x74, 0x7c, 0x3a, 0x72, 0x7a,
+  0x36, 0x6e, 0x76, 0x34, 0x6b, 0x75, 0x31, 0x68, 0x72, 0x2e, 0x66, 0x6f,
+  0x2b, 0x63, 0x6c, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x24, 0x5d, 0x66,
+  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
+  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc4, 0xd7, 0xd9, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xfe, 0x5b, 0x8e, 0x95,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x6c, 0x90, 0x96,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x92, 0x97, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf1, 0xf4, 0xf4, 0x19, 0x3f, 0x45, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x0a, 0x2b, 0x30, 0xb3, 0xbd, 0xbe, 0xff, 0xff, 0xff, 0x91, 0x9e, 0xa1,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
+  0x01, 0x0c, 0x0e, 0xa0, 0xab, 0xac, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xc8, 0xda, 0xdd, 0x86, 0xac, 0xb2, 0x81, 0xa9, 0xaf, 0x7d, 0xa5, 0xac,
+  0x78, 0xa2, 0xa9, 0x73, 0x9e, 0xa5, 0x6f, 0x9b, 0xa1, 0x6a, 0x97, 0x9e,
+  0x65, 0x94, 0x9b, 0x61, 0x91, 0x98, 0x5c, 0x8d, 0x95, 0x59, 0x8a, 0x92,
+  0x54, 0x86, 0x8e, 0x50, 0x83, 0x8b, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
+  0x46, 0x7a, 0x83, 0x42, 0x78, 0x80, 0x3e, 0x74, 0x7d, 0x3a, 0x72, 0x7a,
+  0x37, 0x6f, 0x77, 0x34, 0x6c, 0x75, 0x31, 0x68, 0x72, 0x2f, 0x67, 0x70,
+  0x2c, 0x64, 0x6d, 0x29, 0x62, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x22, 0x5a, 0x64, 0x20, 0x59, 0x61, 0x1f, 0x57, 0x61, 0x1e, 0x56, 0x5f,
+  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc4, 0xd7, 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf9, 0xf9,
+  0x4a, 0x82, 0x8a, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x08, 0x46, 0x4f, 0xcb, 0xd8, 0xda,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xda, 0xdc, 0x0a, 0x44, 0x4d,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x3c, 0x56, 0x5a, 0xff, 0xff, 0xff, 0xd1, 0xd7, 0xd8,
+  0x06, 0x23, 0x27, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
+  0x01, 0x0c, 0x0e, 0x88, 0x95, 0x97, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xb4, 0xcd, 0xd0, 0x87, 0xad, 0xb3, 0x82, 0xaa, 0xb0, 0x7d, 0xa6, 0xad,
+  0x79, 0xa2, 0xa9, 0x74, 0x9f, 0xa6, 0x70, 0x9b, 0xa2, 0x6b, 0x98, 0x9f,
+  0x66, 0x94, 0x9c, 0x62, 0x92, 0x99, 0x5d, 0x8e, 0x96, 0x59, 0x8a, 0x92,
+  0x55, 0x87, 0x8f, 0x50, 0x83, 0x8b, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
+  0x46, 0x7a, 0x83, 0x42, 0x78, 0x80, 0x3e, 0x74, 0x7d, 0x3b, 0x72, 0x7a,
+  0x37, 0x6f, 0x77, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
+  0x2c, 0x64, 0x6d, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x26, 0x5e, 0x67,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1c, 0x54, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc4, 0xd7, 0xd9, 0xff, 0xff, 0xff, 0xdc, 0xe7, 0xe8, 0xff, 0xff, 0xff,
+  0xec, 0xf2, 0xf3, 0x3a, 0x77, 0x7f, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x44, 0x73, 0x7a, 0xfe, 0xfe, 0xfe,
+  0xf2, 0xf5, 0xf6, 0xf5, 0xf8, 0xf8, 0xff, 0xff, 0xff, 0x4a, 0x75, 0x7c,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x1b, 0x39, 0x3d, 0xfe, 0xfe, 0xfe, 0xe5, 0xe8, 0xe9,
+  0x0a, 0x27, 0x2b, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
+  0x00, 0x0b, 0x0d, 0x78, 0x87, 0x8a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xa6, 0xc3, 0xc7, 0x87, 0xad, 0xb3, 0x82, 0xaa, 0xb0, 0x7d, 0xa6, 0xad,
+  0x79, 0xa2, 0xa9, 0x74, 0x9f, 0xa6, 0x70, 0x9b, 0xa2, 0x6c, 0x99, 0xa0,
+  0x67, 0x95, 0x9d, 0x62, 0x92, 0x99, 0x5e, 0x8e, 0x97, 0x5a, 0x8a, 0x93,
+  0x55, 0x87, 0x8f, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
+  0x45, 0x7a, 0x82, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
+  0x38, 0x6f, 0x78, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x26, 0x5e, 0x67,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1c, 0x54, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x4b, 0x83, 0x8b, 0xb4, 0xcb, 0xce,
+  0xff, 0xff, 0xff, 0xe0, 0xe9, 0xeb, 0x2a, 0x6c, 0x75, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0xa3, 0xba, 0xbd, 0xff, 0xff, 0xff,
+  0x94, 0xaf, 0xb2, 0x89, 0xa6, 0xaa, 0xff, 0xff, 0xff, 0xae, 0xc2, 0xc4,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x3a, 0x54, 0x58, 0xff, 0xff, 0xff, 0xd1, 0xd7, 0xd8,
+  0x06, 0x23, 0x27, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
+  0x00, 0x0b, 0x0d, 0x6b, 0x7c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xa0, 0xbf, 0xc4, 0x88, 0xae, 0xb4, 0x83, 0xaa, 0xb0, 0x7e, 0xa7, 0xad,
+  0x7a, 0xa3, 0xaa, 0x75, 0xa0, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0,
+  0x67, 0x95, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8a, 0x93,
+  0x56, 0x88, 0x90, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
+  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
+  0x38, 0x6f, 0x78, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x26, 0x5e, 0x67,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x38, 0x75, 0x7e, 0x12, 0x5b, 0x66,
+  0xcb, 0xdb, 0xde, 0xff, 0xff, 0xff, 0xd2, 0xe0, 0xe2, 0x1d, 0x61, 0x6b,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x21, 0x5a, 0x62, 0xf1, 0xf5, 0xf5, 0xfe, 0xfe, 0xfe,
+  0x32, 0x66, 0x6d, 0x26, 0x5c, 0x64, 0xf9, 0xfb, 0xfb, 0xf7, 0xf9, 0xf9,
+  0x29, 0x5c, 0x63, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x12, 0x32, 0x37, 0xb9, 0xc2, 0xc3, 0xff, 0xff, 0xff, 0x89, 0x97, 0x9a,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
+  0x00, 0x0a, 0x0c, 0x64, 0x75, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xfc, 0xfc,
+  0x9d, 0xbc, 0xc1, 0x89, 0xae, 0xb4, 0x83, 0xaa, 0xb0, 0x7e, 0xa7, 0xad,
+  0x7a, 0xa3, 0xaa, 0x75, 0xa0, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0,
+  0x68, 0x96, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8b, 0x93,
+  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
+  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
+  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x32, 0x69, 0x72, 0x30, 0x68, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x26, 0x5e, 0x67,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x43, 0x7d, 0x85, 0x06, 0x53, 0x5e,
+  0x23, 0x68, 0x72, 0xd8, 0xe4, 0xe6, 0xff, 0xff, 0xff, 0xc3, 0xd5, 0xd8,
+  0x11, 0x59, 0x64, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x78, 0x9a, 0x9f, 0xff, 0xff, 0xff, 0xc2, 0xd1, 0xd4,
+  0x05, 0x44, 0x4d, 0x04, 0x42, 0x4b, 0xb4, 0xc6, 0xc9, 0xff, 0xff, 0xff,
+  0x89, 0xa5, 0xa9, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x20, 0x45, 0x4a, 0x33, 0x55, 0x59,
+  0x47, 0x64, 0x68, 0x46, 0x62, 0x66, 0x55, 0x6e, 0x72, 0x84, 0x96, 0x98,
+  0xdb, 0xe0, 0xe1, 0xff, 0xff, 0xff, 0xcd, 0xd4, 0xd5, 0x18, 0x34, 0x39,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
+  0x00, 0x0a, 0x0c, 0x61, 0x73, 0x76, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfb, 0xfb,
+  0x9c, 0xbc, 0xc1, 0x89, 0xae, 0xb4, 0x84, 0xab, 0xb1, 0x7f, 0xa7, 0xae,
+  0x7b, 0xa4, 0xaa, 0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa3, 0x6d, 0x99, 0xa0,
+  0x68, 0x96, 0x9d, 0x63, 0x92, 0x9a, 0x5f, 0x8f, 0x97, 0x5a, 0x8b, 0x93,
+  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
+  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3c, 0x73, 0x7b,
+  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x33, 0x6a, 0x73, 0x30, 0x68, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x2f, 0x6f, 0x78, 0xe4, 0xec, 0xed, 0xff, 0xff, 0xff,
+  0xb3, 0xca, 0xcd, 0x0b, 0x55, 0x5f, 0x05, 0x50, 0x5b, 0x7e, 0xa4, 0xaa,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x0c, 0x4b, 0x54, 0xd6, 0xe0, 0xe2, 0xff, 0xff, 0xff, 0x61, 0x88, 0x8f,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x4f, 0x7a, 0x80, 0xff, 0xff, 0xff,
+  0xe1, 0xe8, 0xe9, 0x14, 0x4a, 0x53, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x19, 0x3f, 0x45, 0x4e, 0x6b, 0x6f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfe, 0xfe, 0xfe, 0x9e, 0xab, 0xad, 0x17, 0x35, 0x39, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
+  0x00, 0x0a, 0x0c, 0x61, 0x73, 0x76, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfc,
+  0x9e, 0xbd, 0xc2, 0x89, 0xae, 0xb4, 0x84, 0xab, 0xb1, 0x7f, 0xa7, 0xae,
+  0x7b, 0xa4, 0xaa, 0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa3, 0x6d, 0x99, 0xa0,
+  0x68, 0x96, 0x9d, 0x64, 0x93, 0x9a, 0x5f, 0x8f, 0x97, 0x5a, 0x8b, 0x93,
+  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
+  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3c, 0x73, 0x7b,
+  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x33, 0x6a, 0x73, 0x30, 0x68, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2e, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe6,
+  0x0b, 0x5c, 0x68, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x74, 0xa2, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xb4, 0xb9, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x3a, 0x77, 0x7f, 0xec, 0xf2, 0xf3,
+  0xff, 0xff, 0xff, 0x9f, 0xbc, 0xc0, 0x05, 0x50, 0x5b, 0x7b, 0xa2, 0xa8,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x4f, 0x7c, 0x83, 0xff, 0xff, 0xff, 0xe2, 0xe9, 0xea, 0x14, 0x4e, 0x57,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x0a, 0x45, 0x4e, 0xd2, 0xdd, 0xde,
+  0xff, 0xff, 0xff, 0x62, 0x87, 0x8c, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x22, 0x47, 0x4c, 0x03, 0x2c, 0x32,
+  0x6a, 0x81, 0x84, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa4, 0xb1, 0xb3,
+  0x27, 0x44, 0x48, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
+  0x00, 0x0b, 0x0c, 0x66, 0x77, 0x7a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xa2, 0xc0, 0xc4, 0x89, 0xae, 0xb4, 0x84, 0xab, 0xb1, 0x7f, 0xa7, 0xae,
+  0x7b, 0xa4, 0xaa, 0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa3, 0x6d, 0x99, 0xa0,
+  0x68, 0x96, 0x9d, 0x63, 0x92, 0x9a, 0x5f, 0x8f, 0x97, 0x5a, 0x8b, 0x93,
+  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
+  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3c, 0x73, 0x7b,
+  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x33, 0x6a, 0x73, 0x30, 0x68, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x2f, 0x75, 0x7f, 0xff, 0xff, 0xff, 0xd5, 0xe3, 0xe5,
+  0x0a, 0x5c, 0x67, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x72, 0xa1, 0xa7, 0xff, 0xff, 0xff, 0x91, 0xb5, 0xba, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x47, 0x7f, 0x87,
+  0xf5, 0xf8, 0xf9, 0xff, 0xff, 0xff, 0x7b, 0xa2, 0xa8, 0x78, 0xa0, 0xa6,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0xaf, 0xc4, 0xc6, 0xff, 0xff, 0xff, 0x88, 0xa6, 0xab, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x6e, 0x91, 0x96,
+  0xff, 0xff, 0xff, 0xc5, 0xd2, 0xd4, 0x06, 0x40, 0x47, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x8e, 0x9f, 0xa2, 0xff, 0xff, 0xff, 0xdb, 0xe1, 0xe1,
+  0x26, 0x43, 0x47, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x11,
+  0x00, 0x0b, 0x0d, 0x6e, 0x7f, 0x82, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xa9, 0xc5, 0xc9, 0x89, 0xae, 0xb4, 0x84, 0xab, 0xb1, 0x7f, 0xa7, 0xae,
+  0x7b, 0xa4, 0xaa, 0x76, 0xa0, 0xa7, 0x71, 0x9d, 0xa3, 0x6d, 0x99, 0xa0,
+  0x68, 0x96, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8b, 0x93,
+  0x56, 0x88, 0x90, 0x52, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
+  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
+  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x33, 0x6a, 0x73, 0x30, 0x68, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x15, 0x4a, 0x52,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x29, 0x71, 0x7c, 0xff, 0xff, 0xff, 0xe0, 0xea, 0xec,
+  0x0a, 0x5c, 0x67, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x7b, 0xa7, 0xad, 0xff, 0xff, 0xff, 0x8d, 0xb2, 0xb7, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x54, 0x88, 0x90, 0xfa, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xdb, 0xe6, 0xe7,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x2a, 0x62, 0x6a,
+  0xf6, 0xf8, 0xf9, 0xf9, 0xfb, 0xfb, 0x2c, 0x61, 0x69, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x1b, 0x51, 0x59,
+  0xe9, 0xee, 0xef, 0xfd, 0xfd, 0xfe, 0x3e, 0x6b, 0x71, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x07, 0x2c, 0x32, 0xb1, 0xbc, 0xbe, 0xff, 0xff, 0xff,
+  0xd5, 0xdb, 0xdc, 0x1d, 0x3a, 0x3f, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
+  0x00, 0x0b, 0x0d, 0x7d, 0x8c, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xb8, 0xcf, 0xd3, 0x88, 0xae, 0xb4, 0x83, 0xaa, 0xb0, 0x7e, 0xa7, 0xad,
+  0x7a, 0xa3, 0xaa, 0x75, 0xa0, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0,
+  0x67, 0x95, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8b, 0x93,
+  0x56, 0x88, 0x90, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
+  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
+  0x38, 0x6f, 0x78, 0x35, 0x6c, 0x76, 0x32, 0x69, 0x72, 0x30, 0x68, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x26, 0x5e, 0x67,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1d, 0x55, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x39, 0x7c, 0x86,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x12, 0x62, 0x6d, 0xe1, 0xeb, 0xec, 0xfc, 0xfd, 0xfd,
+  0x47, 0x85, 0x8d, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x07, 0x59, 0x65,
+  0xc7, 0xda, 0xdc, 0xff, 0xff, 0xff, 0x5f, 0x94, 0x9b, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x63, 0x93, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x83, 0xa4, 0xa9,
+  0xff, 0xff, 0xff, 0xb0, 0xc4, 0xc7, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x92, 0xab, 0xaf, 0xff, 0xff, 0xff, 0xa1, 0xb7, 0xba, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x15, 0x37, 0x3d, 0xcf, 0xd5, 0xd6,
+  0xff, 0xff, 0xff, 0xc1, 0xc9, 0xca, 0x0d, 0x2c, 0x30, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
+  0x01, 0x0c, 0x0e, 0x90, 0x9d, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xcc, 0xdd, 0xdf, 0x88, 0xae, 0xb4, 0x83, 0xaa, 0xb0, 0x7e, 0xa7, 0xad,
+  0x7a, 0xa3, 0xaa, 0x75, 0xa0, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0,
+  0x67, 0x95, 0x9d, 0x63, 0x92, 0x9a, 0x5e, 0x8e, 0x97, 0x5a, 0x8a, 0x93,
+  0x56, 0x88, 0x90, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4b, 0x7e, 0x87,
+  0x47, 0x7b, 0x84, 0x42, 0x78, 0x80, 0x3f, 0x75, 0x7e, 0x3b, 0x72, 0x7a,
+  0x38, 0x6f, 0x78, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
+  0x2d, 0x65, 0x6d, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x26, 0x5e, 0x67,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1c, 0x54, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xce, 0xdf, 0xe1, 0xff, 0xff, 0xff, 0x2e, 0x75, 0x7f,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x82, 0xac, 0xb2, 0xff, 0xff, 0xff,
+  0xd9, 0xe6, 0xe7, 0x35, 0x78, 0x82, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x0f, 0x5e, 0x69, 0x93, 0xb6, 0xbc,
+  0xff, 0xff, 0xff, 0xdf, 0xe9, 0xeb, 0x16, 0x62, 0x6d, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x74, 0x9e, 0xa4, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x83, 0xa8, 0xad, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x10, 0x4f, 0x59, 0xdf, 0xe7, 0xe8,
+  0xff, 0xff, 0xff, 0x4e, 0x7b, 0x81, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x31, 0x62, 0x69, 0xf9, 0xfa, 0xfb, 0xf1, 0xf4, 0xf5, 0x22, 0x54, 0x5b,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x2c, 0x4a, 0x4e,
+  0xe6, 0xea, 0xea, 0xff, 0xff, 0xff, 0xa8, 0xb3, 0xb4, 0x04, 0x23, 0x28,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0e, 0x10,
+  0x01, 0x0d, 0x0f, 0xa6, 0xb1, 0xb2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xe1, 0xeb, 0xec, 0x87, 0xad, 0xb3, 0x82, 0xaa, 0xb0, 0x7d, 0xa6, 0xad,
+  0x79, 0xa2, 0xa9, 0x74, 0x9f, 0xa6, 0x70, 0x9b, 0xa2, 0x6b, 0x98, 0x9f,
+  0x66, 0x94, 0x9c, 0x62, 0x92, 0x99, 0x5d, 0x8e, 0x96, 0x5a, 0x8a, 0x93,
+  0x55, 0x87, 0x8f, 0x51, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
+  0x46, 0x7a, 0x83, 0x42, 0x78, 0x80, 0x3e, 0x74, 0x7d, 0x3b, 0x72, 0x7a,
+  0x37, 0x6f, 0x77, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
+  0x2c, 0x64, 0x6d, 0x2a, 0x63, 0x6b, 0x26, 0x60, 0x69, 0x26, 0x5e, 0x67,
+  0x24, 0x5c, 0x65, 0x22, 0x5a, 0x63, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1c, 0x54, 0x5d, 0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xcd, 0xde, 0xe1, 0xff, 0xff, 0xff, 0x97, 0xbb, 0xc0,
+  0x7b, 0xa8, 0xaf, 0x7d, 0xa9, 0xb0, 0x7d, 0xa9, 0xb0, 0x7e, 0xaa, 0xb0,
+  0x77, 0xa6, 0xac, 0x1a, 0x68, 0x73, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x11, 0x61, 0x6d, 0xc1, 0xd5, 0xd8,
+  0xff, 0xff, 0xff, 0xf4, 0xf8, 0xf8, 0xa7, 0xc4, 0xc9, 0x80, 0xaa, 0xb0,
+  0x7b, 0xa7, 0xad, 0x92, 0xb6, 0xbb, 0xd4, 0xe2, 0xe4, 0xff, 0xff, 0xff,
+  0xf8, 0xfa, 0xfb, 0x4b, 0x86, 0x8e, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xc5, 0xd7, 0xda, 0xff, 0xff, 0xff, 0x42, 0x7c, 0x85, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x85, 0xaa, 0xaf,
+  0xff, 0xff, 0xff, 0x85, 0xa9, 0xae, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x5a, 0x86, 0x8c, 0xff, 0xff, 0xff,
+  0xd4, 0xdf, 0xe1, 0x0c, 0x4a, 0x53, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0xb4, 0xc5, 0xc8, 0xff, 0xff, 0xff, 0x7b, 0x99, 0x9d,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x16, 0x40, 0x46,
+  0xe3, 0xe8, 0xe9, 0xf2, 0xf4, 0xf5, 0x23, 0x47, 0x4d, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x45, 0x5e, 0x62, 0xf8, 0xf9, 0xf9, 0xff, 0xff, 0xff, 0x8d, 0x9b, 0x9d,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x01, 0x0d, 0x10,
+  0x03, 0x12, 0x15, 0xb8, 0xbf, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xf4, 0xf8, 0xf8, 0x93, 0xb5, 0xba, 0x81, 0xa9, 0xaf, 0x7d, 0xa5, 0xac,
+  0x78, 0xa2, 0xa9, 0x73, 0x9e, 0xa5, 0x70, 0x9b, 0xa2, 0x6b, 0x98, 0x9f,
+  0x66, 0x94, 0x9c, 0x61, 0x91, 0x98, 0x5d, 0x8e, 0x96, 0x59, 0x8a, 0x92,
+  0x55, 0x87, 0x8f, 0x50, 0x83, 0x8b, 0x4d, 0x81, 0x89, 0x4a, 0x7e, 0x86,
+  0x46, 0x7a, 0x83, 0x42, 0x78, 0x80, 0x3e, 0x74, 0x7d, 0x3a, 0x72, 0x7a,
+  0x37, 0x6f, 0x77, 0x34, 0x6c, 0x75, 0x32, 0x69, 0x72, 0x2f, 0x67, 0x70,
+  0x2c, 0x64, 0x6d, 0x2a, 0x63, 0x6b, 0x27, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x20, 0x58, 0x61, 0x1e, 0x56, 0x5f,
+  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x11, 0x45, 0x4d,
+  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0xd8, 0xe5, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x33, 0x79, 0x82, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x18, 0x65, 0x70,
+  0x9e, 0xbf, 0xc3, 0xf9, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xdf, 0xe1,
+  0x49, 0x85, 0x8e, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0xcf, 0xde, 0xe0, 0xff, 0xff, 0xff, 0x44, 0x7e, 0x86, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0xa6, 0xc0, 0xc4, 0x8e, 0xaf, 0xb4, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x08, 0x4a, 0x53, 0xc5, 0xd4, 0xd7, 0xff, 0xff, 0xff,
+  0x76, 0x99, 0x9e, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x4f, 0x78, 0x7e, 0xff, 0xff, 0xff, 0xe5, 0xeb, 0xec,
+  0x15, 0x49, 0x50, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x17, 0x41, 0x47,
+  0xef, 0xf2, 0xf2, 0xff, 0xff, 0xff, 0x25, 0x49, 0x4e, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x69, 0x7c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x7f, 0x8e, 0x90, 0x10, 0x2a, 0x2f, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0d, 0x0f,
+  0x0a, 0x1c, 0x1f, 0xcc, 0xd1, 0xd2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xaa, 0xc5, 0xc9, 0x81, 0xa9, 0xaf, 0x7d, 0xa5, 0xac,
+  0x78, 0xa2, 0xa9, 0x73, 0x9e, 0xa5, 0x6f, 0x9b, 0xa1, 0x6a, 0x97, 0x9e,
+  0x66, 0x94, 0x9c, 0x61, 0x91, 0x98, 0x5c, 0x8d, 0x95, 0x58, 0x89, 0x92,
+  0x54, 0x86, 0x8e, 0x50, 0x83, 0x8b, 0x4c, 0x80, 0x88, 0x49, 0x7d, 0x86,
+  0x44, 0x79, 0x82, 0x41, 0x77, 0x7f, 0x3e, 0x74, 0x7d, 0x3a, 0x72, 0x7a,
+  0x37, 0x6f, 0x77, 0x34, 0x6b, 0x75, 0x31, 0x68, 0x72, 0x2f, 0x67, 0x70,
+  0x2c, 0x64, 0x6d, 0x29, 0x62, 0x6b, 0x26, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1e, 0x56, 0x5f,
+  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x13, 0x49, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0x34, 0x60, 0x67,
+  0x3f, 0x68, 0x6e, 0x3b, 0x65, 0x6b, 0x3b, 0x64, 0x6a, 0x3b, 0x63, 0x6a,
+  0x3b, 0x63, 0x69, 0x3b, 0x62, 0x68, 0x3b, 0x62, 0x68, 0x2b, 0x54, 0x5b,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x6b, 0x9d, 0xa4, 0x86, 0xaf, 0xb5, 0x84, 0xae, 0xb4,
+  0x84, 0xae, 0xb4, 0x84, 0xae, 0xb4, 0x84, 0xae, 0xb4, 0x85, 0xaf, 0xb4,
+  0x7e, 0xaa, 0xb0, 0x1b, 0x69, 0x74, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x32, 0x76, 0x80, 0x68, 0x9a, 0xa1, 0x83, 0xac, 0xb2,
+  0x85, 0xae, 0xb4, 0x77, 0xa5, 0xab, 0x4b, 0x86, 0x8f, 0x0f, 0x5e, 0x69,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x72, 0x9e, 0xa5, 0x98, 0xb9, 0xbd, 0x27, 0x6a, 0x73, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x0f, 0x56, 0x60, 0x36, 0x71, 0x7a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x1c, 0x59, 0x61, 0xa7, 0xbe, 0xc2, 0xa7, 0xbe, 0xc1,
+  0x1c, 0x57, 0x5f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x0a, 0x43, 0x4b, 0x96, 0xae, 0xb1, 0xb3, 0xc4, 0xc7,
+  0x2f, 0x5e, 0x64, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x0d, 0x39, 0x3f,
+  0x74, 0x8c, 0x90, 0x7c, 0x92, 0x95, 0x13, 0x3a, 0x40, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x62, 0x77, 0x79, 0x86, 0x95, 0x97,
+  0x7e, 0x8d, 0x8f, 0x2e, 0x45, 0x49, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0b, 0x0d,
+  0x14, 0x29, 0x2c, 0xe5, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xd1, 0xdf, 0xe2, 0x7f, 0xa8, 0xae, 0x7b, 0xa4, 0xab,
+  0x77, 0xa1, 0xa8, 0x72, 0x9e, 0xa4, 0x6e, 0x9a, 0xa1, 0x69, 0x97, 0x9e,
+  0x65, 0x94, 0x9b, 0x5f, 0x90, 0x97, 0x5b, 0x8c, 0x95, 0x58, 0x89, 0x92,
+  0x53, 0x86, 0x8e, 0x4f, 0x82, 0x8b, 0x4c, 0x80, 0x88, 0x49, 0x7d, 0x86,
+  0x45, 0x7a, 0x82, 0x41, 0x77, 0x7f, 0x3d, 0x74, 0x7c, 0x3a, 0x72, 0x7a,
+  0x36, 0x6e, 0x76, 0x34, 0x6b, 0x75, 0x31, 0x68, 0x72, 0x2e, 0x66, 0x6f,
+  0x2c, 0x64, 0x6d, 0x29, 0x62, 0x6b, 0x26, 0x60, 0x69, 0x25, 0x5d, 0x66,
+  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
+  0x1c, 0x54, 0x5d, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xcc, 0xd7, 0xd9,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xbe, 0xc1,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
@@ -9063,22 +8743,278 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x12, 0x00, 0x0c, 0x0e,
-  0x79, 0x8e, 0x91, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0a, 0x0c,
+  0x23, 0x3a, 0x3d, 0xfb, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0xf0, 0xf1, 0x7a, 0xa4, 0xaa,
-  0x70, 0x9c, 0xa3, 0x6b, 0x99, 0xa0, 0x66, 0x95, 0x9c, 0x63, 0x92, 0x9a,
-  0x5f, 0x8f, 0x97, 0x5a, 0x8c, 0x94, 0x56, 0x89, 0x91, 0x52, 0x85, 0x8e,
-  0x4e, 0x83, 0x8b, 0x4b, 0x7f, 0x88, 0x47, 0x7d, 0x85, 0x43, 0x79, 0x82,
-  0x40, 0x76, 0x7f, 0x3d, 0x74, 0x7c, 0x39, 0x71, 0x7a, 0x36, 0x6f, 0x77,
-  0x34, 0x6c, 0x75, 0x31, 0x69, 0x73, 0x2e, 0x66, 0x70, 0x2c, 0x65, 0x6e,
-  0x29, 0x62, 0x6b, 0x26, 0x60, 0x69, 0x25, 0x5e, 0x67, 0x23, 0x5c, 0x65,
-  0x21, 0x5a, 0x63, 0x1f, 0x58, 0x61, 0x1d, 0x56, 0x5f, 0x1c, 0x54, 0x5e,
+  0xff, 0xff, 0xff, 0xf2, 0xf6, 0xf7, 0x8b, 0xb0, 0xb5, 0x7a, 0xa4, 0xaa,
+  0x75, 0xa0, 0xa7, 0x71, 0x9d, 0xa4, 0x6d, 0x99, 0xa0, 0x68, 0x96, 0x9d,
+  0x64, 0x92, 0x9a, 0x5f, 0x90, 0x97, 0x5a, 0x8c, 0x94, 0x57, 0x88, 0x91,
+  0x52, 0x85, 0x8d, 0x4e, 0x82, 0x8a, 0x4b, 0x7f, 0x88, 0x48, 0x7c, 0x85,
+  0x44, 0x79, 0x82, 0x40, 0x76, 0x7e, 0x3d, 0x74, 0x7c, 0x39, 0x71, 0x79,
+  0x36, 0x6e, 0x76, 0x33, 0x6a, 0x74, 0x31, 0x68, 0x72, 0x2e, 0x66, 0x6f,
+  0x2b, 0x63, 0x6c, 0x29, 0x62, 0x6b, 0x26, 0x5f, 0x68, 0x25, 0x5d, 0x66,
+  0x23, 0x5b, 0x64, 0x21, 0x5a, 0x62, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
+  0x1b, 0x53, 0x5c, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xc9, 0xd5, 0xd7,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x13, 0x00, 0x0a, 0x0c,
+  0x37, 0x4f, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb4, 0xcc, 0xd0, 0x79, 0xa3, 0xaa,
+  0x74, 0x9f, 0xa6, 0x70, 0x9c, 0xa3, 0x6c, 0x99, 0xa0, 0x67, 0x96, 0x9d,
+  0x63, 0x92, 0x9a, 0x5e, 0x8f, 0x97, 0x5a, 0x8b, 0x94, 0x56, 0x88, 0x90,
+  0x51, 0x85, 0x8d, 0x4d, 0x81, 0x89, 0x4a, 0x7f, 0x87, 0x47, 0x7c, 0x84,
+  0x42, 0x78, 0x80, 0x3f, 0x76, 0x7e, 0x3c, 0x73, 0x7c, 0x38, 0x70, 0x79,
+  0x35, 0x6d, 0x76, 0x33, 0x6a, 0x74, 0x30, 0x68, 0x71, 0x2d, 0x65, 0x6e,
+  0x2a, 0x63, 0x6b, 0x28, 0x61, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x66,
+  0x21, 0x5a, 0x63, 0x20, 0x59, 0x61, 0x1f, 0x57, 0x61, 0x1d, 0x55, 0x5e,
+  0x1b, 0x53, 0x5c, 0x19, 0x52, 0x5a, 0x18, 0x51, 0x5a, 0x17, 0x4f, 0x58,
+  0x17, 0x4e, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xc9, 0xd5, 0xd7,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x12, 0x00, 0x0b, 0x0d,
+  0x59, 0x71, 0x75, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0xf0, 0xf1, 0x7e, 0xa6, 0xad,
+  0x73, 0x9e, 0xa6, 0x6f, 0x9b, 0xa2, 0x6a, 0x97, 0x9e, 0x66, 0x95, 0x9c,
+  0x62, 0x91, 0x99, 0x5d, 0x8e, 0x96, 0x59, 0x8a, 0x93, 0x55, 0x87, 0x90,
+  0x50, 0x84, 0x8c, 0x4d, 0x81, 0x89, 0x49, 0x7e, 0x86, 0x45, 0x7a, 0x83,
+  0x42, 0x78, 0x80, 0x3f, 0x76, 0x7e, 0x3b, 0x72, 0x7b, 0x38, 0x70, 0x79,
+  0x34, 0x6d, 0x75, 0x32, 0x6a, 0x73, 0x30, 0x68, 0x71, 0x2d, 0x65, 0x6e,
+  0x2a, 0x63, 0x6b, 0x28, 0x61, 0x6a, 0x25, 0x5e, 0x67, 0x24, 0x5d, 0x66,
+  0x22, 0x5a, 0x64, 0x1f, 0x58, 0x61, 0x1e, 0x57, 0x60, 0x1d, 0x55, 0x5e,
+  0x1b, 0x53, 0x5c, 0x19, 0x52, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
+  0x16, 0x4d, 0x56, 0x16, 0x4c, 0x55, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xc9, 0xd5, 0xd7,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x12, 0x00, 0x0d, 0x0f,
+  0x8e, 0x9f, 0xa2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xc7, 0xcb,
+  0x71, 0x9d, 0xa4, 0x6e, 0x9b, 0xa1, 0x69, 0x97, 0x9e, 0x64, 0x94, 0x9b,
+  0x61, 0x90, 0x98, 0x5b, 0x8d, 0x95, 0x58, 0x8a, 0x92, 0x54, 0x86, 0x8f,
+  0x4f, 0x83, 0x8b, 0x4c, 0x80, 0x88, 0x48, 0x7d, 0x86, 0x44, 0x7a, 0x82,
+  0x41, 0x77, 0x80, 0x3e, 0x75, 0x7d, 0x3a, 0x72, 0x7b, 0x37, 0x6f, 0x78,
+  0x34, 0x6d, 0x75, 0x32, 0x6a, 0x73, 0x2f, 0x67, 0x70, 0x2c, 0x65, 0x6e,
+  0x2a, 0x63, 0x6b, 0x27, 0x60, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x66,
+  0x22, 0x5a, 0x64, 0x20, 0x59, 0x61, 0x1e, 0x57, 0x60, 0x1c, 0x54, 0x5e,
+  0x1b, 0x53, 0x5c, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
+  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x15, 0x4a, 0x53, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x12, 0x47, 0x50, 0x11, 0x45, 0x4e, 0xc9, 0xd5, 0xd7,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x0f, 0x12, 0x03, 0x12, 0x14,
+  0xc5, 0xcf, 0xd1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed, 0xf3, 0xf4,
+  0x7b, 0xa5, 0xab, 0x6c, 0x99, 0xa0, 0x67, 0x96, 0x9d, 0x64, 0x93, 0x9a,
+  0x5f, 0x8f, 0x97, 0x5a, 0x8c, 0x94, 0x57, 0x89, 0x92, 0x52, 0x85, 0x8e,
+  0x4e, 0x83, 0x8b, 0x4b, 0x7f, 0x88, 0x47, 0x7d, 0x85, 0x44, 0x7a, 0x82,
+  0x41, 0x77, 0x80, 0x3d, 0x74, 0x7c, 0x39, 0x71, 0x7a, 0x36, 0x6f, 0x77,
+  0x34, 0x6c, 0x75, 0x31, 0x69, 0x73, 0x2f, 0x67, 0x70, 0x2c, 0x65, 0x6e,
+  0x29, 0x62, 0x6b, 0x27, 0x60, 0x6a, 0x25, 0x5e, 0x67, 0x23, 0x5c, 0x65,
+  0x20, 0x59, 0x62, 0x1f, 0x58, 0x61, 0x1e, 0x57, 0x60, 0x1c, 0x54, 0x5e,
   0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
   0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x14, 0x4a, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
-  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x23, 0x4e, 0x56, 0x36, 0x5d, 0x64,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -9127,86 +9063,22 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x01, 0x10, 0x12, 0x01, 0x0e, 0x11,
-  0xb5, 0xc1, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0e, 0x0f, 0x10, 0x24, 0x27,
+  0xe8, 0xec, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xc8, 0xcc,
-  0x6e, 0x9b, 0xa2, 0x69, 0x97, 0x9e, 0x65, 0x94, 0x9b, 0x61, 0x91, 0x98,
-  0x5d, 0x8e, 0x96, 0x59, 0x8b, 0x93, 0x55, 0x88, 0x90, 0x50, 0x84, 0x8d,
-  0x4d, 0x81, 0x8a, 0x49, 0x7e, 0x86, 0x46, 0x7c, 0x84, 0x42, 0x78, 0x81,
-  0x40, 0x76, 0x7f, 0x3c, 0x74, 0x7c, 0x38, 0x70, 0x79, 0x35, 0x6e, 0x77,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xbf, 0xd3, 0xd6, 0x6a, 0x98, 0x9f, 0x66, 0x95, 0x9c, 0x62, 0x92, 0x99,
+  0x5e, 0x8e, 0x97, 0x5a, 0x8c, 0x94, 0x55, 0x88, 0x90, 0x51, 0x85, 0x8d,
+  0x4d, 0x82, 0x8a, 0x4a, 0x7f, 0x87, 0x46, 0x7c, 0x84, 0x43, 0x79, 0x82,
+  0x40, 0x76, 0x7f, 0x3c, 0x74, 0x7c, 0x39, 0x71, 0x7a, 0x35, 0x6e, 0x77,
   0x33, 0x6b, 0x74, 0x30, 0x68, 0x72, 0x2e, 0x66, 0x70, 0x2b, 0x64, 0x6d,
   0x28, 0x61, 0x6a, 0x26, 0x60, 0x69, 0x25, 0x5e, 0x67, 0x23, 0x5c, 0x65,
-  0x21, 0x5a, 0x63, 0x1f, 0x58, 0x61, 0x1d, 0x56, 0x5f, 0x1b, 0x53, 0x5d,
+  0x21, 0x5a, 0x63, 0x1e, 0x57, 0x60, 0x1d, 0x56, 0x5f, 0x1c, 0x54, 0x5e,
   0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
-  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
-  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x85, 0x9d, 0xa1, 0x98, 0xac, 0xaf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0e, 0x10, 0x0a, 0x1c, 0x1f,
-  0xdb, 0xe1, 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x14, 0x4a, 0x51,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf5, 0xf6,
-  0x7b, 0xa3, 0xab, 0x68, 0x97, 0x9e, 0x64, 0x93, 0x9a, 0x60, 0x90, 0x98,
-  0x5b, 0x8c, 0x95, 0x57, 0x8a, 0x92, 0x53, 0x87, 0x8f, 0x4f, 0x83, 0x8c,
-  0x4c, 0x81, 0x89, 0x48, 0x7d, 0x86, 0x44, 0x7b, 0x83, 0x41, 0x78, 0x81,
-  0x3f, 0x75, 0x7e, 0x3a, 0x72, 0x7b, 0x37, 0x6f, 0x79, 0x34, 0x6d, 0x76,
-  0x32, 0x6b, 0x73, 0x2f, 0x68, 0x71, 0x2c, 0x65, 0x6f, 0x2a, 0x63, 0x6c,
-  0x28, 0x61, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x67, 0x22, 0x5b, 0x64,
-  0x20, 0x59, 0x62, 0x1e, 0x57, 0x60, 0x1d, 0x56, 0x5f, 0x1b, 0x53, 0x5d,
-  0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
-  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
-  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x32, 0x5c, 0x61, 0xee, 0xf1, 0xf2, 0xb8, 0xc6, 0xc8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -9255,22 +9127,150 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0b, 0x0d, 0x1f, 0x37, 0x3a,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0b, 0x0d, 0x28, 0x41, 0x44,
   0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xc7, 0xd8, 0xdb, 0x66, 0x96, 0x9d, 0x62, 0x92, 0x99, 0x5e, 0x8f, 0x97,
-  0x5a, 0x8c, 0x94, 0x56, 0x89, 0x91, 0x52, 0x86, 0x8f, 0x4e, 0x83, 0x8c,
-  0x4b, 0x80, 0x88, 0x47, 0x7d, 0x85, 0x43, 0x7a, 0x83, 0x40, 0x77, 0x80,
-  0x3e, 0x74, 0x7d, 0x39, 0x72, 0x7a, 0x36, 0x6f, 0x78, 0x34, 0x6d, 0x75,
-  0x31, 0x6a, 0x73, 0x2e, 0x67, 0x71, 0x2c, 0x65, 0x6f, 0x29, 0x63, 0x6c,
+  0xfd, 0xfe, 0xfe, 0x95, 0xb6, 0xbb, 0x64, 0x94, 0x9b, 0x61, 0x91, 0x98,
+  0x5c, 0x8d, 0x95, 0x58, 0x8b, 0x92, 0x54, 0x87, 0x90, 0x50, 0x84, 0x8d,
+  0x4d, 0x81, 0x8a, 0x49, 0x7e, 0x86, 0x45, 0x7b, 0x84, 0x42, 0x78, 0x81,
+  0x40, 0x76, 0x7f, 0x3b, 0x73, 0x7b, 0x38, 0x70, 0x79, 0x35, 0x6e, 0x77,
+  0x32, 0x6b, 0x73, 0x30, 0x68, 0x72, 0x2d, 0x65, 0x6f, 0x2a, 0x63, 0x6c,
+  0x29, 0x62, 0x6b, 0x26, 0x60, 0x69, 0x23, 0x5d, 0x66, 0x22, 0x5b, 0x64,
+  0x20, 0x59, 0x62, 0x1f, 0x58, 0x61, 0x1d, 0x56, 0x5f, 0x1b, 0x53, 0x5d,
+  0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x59, 0x17, 0x4f, 0x57,
+  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0b, 0x0e, 0x50, 0x6a, 0x6e,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xf2, 0xf3,
+  0xf5, 0xf8, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xeb, 0xf1, 0xf2, 0x75, 0x9e, 0xa5, 0x5f, 0x90, 0x97,
+  0x5b, 0x8c, 0x95, 0x56, 0x89, 0x91, 0x52, 0x86, 0x8f, 0x4f, 0x83, 0x8c,
+  0x4c, 0x81, 0x89, 0x48, 0x7d, 0x86, 0x44, 0x7b, 0x83, 0x40, 0x77, 0x80,
+  0x3e, 0x74, 0x7d, 0x3a, 0x72, 0x7b, 0x37, 0x6f, 0x79, 0x34, 0x6d, 0x76,
+  0x32, 0x6b, 0x73, 0x2f, 0x68, 0x71, 0x2c, 0x65, 0x6f, 0x2a, 0x63, 0x6c,
   0x27, 0x60, 0x6a, 0x26, 0x5f, 0x68, 0x24, 0x5d, 0x67, 0x22, 0x5b, 0x64,
-  0x20, 0x59, 0x62, 0x1e, 0x57, 0x60, 0x1c, 0x55, 0x5f, 0x1b, 0x53, 0x5d,
+  0x1f, 0x58, 0x62, 0x1e, 0x57, 0x60, 0x1d, 0x56, 0x5f, 0x1b, 0x53, 0x5d,
+  0x1a, 0x53, 0x5b, 0x18, 0x51, 0x5a, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
+  0x16, 0x4d, 0x56, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x02, 0x13, 0x16, 0x01, 0x11, 0x14, 0x00, 0x0f, 0x12, 0x9c, 0xac, 0xae,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb5, 0xcd, 0xd1,
+  0xc8, 0xda, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0xe2, 0xe4, 0x64, 0x93, 0x9b,
+  0x59, 0x8b, 0x94, 0x55, 0x89, 0x90, 0x51, 0x85, 0x8e, 0x4d, 0x82, 0x8b,
+  0x4a, 0x7f, 0x88, 0x46, 0x7c, 0x84, 0x43, 0x7a, 0x83, 0x40, 0x77, 0x80,
+  0x3d, 0x74, 0x7d, 0x39, 0x72, 0x7a, 0x36, 0x6f, 0x78, 0x34, 0x6d, 0x75,
+  0x31, 0x6a, 0x73, 0x2e, 0x67, 0x71, 0x2b, 0x64, 0x6e, 0x29, 0x63, 0x6c,
+  0x27, 0x60, 0x6a, 0x25, 0x5e, 0x68, 0x22, 0x5c, 0x65, 0x21, 0x5a, 0x64,
+  0x20, 0x59, 0x62, 0x1d, 0x57, 0x5f, 0x1c, 0x55, 0x5f, 0x1b, 0x53, 0x5d,
   0x19, 0x52, 0x5b, 0x17, 0x50, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
   0x15, 0x4c, 0x55, 0x15, 0x4b, 0x54, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
-  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0xb4, 0xc3, 0xc5, 0xff, 0xff, 0xff, 0xae, 0xbe, 0xc1,
+  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -9319,22 +9319,22 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0b, 0x0d, 0x41, 0x5a, 0x5e,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xf6, 0xf6,
-  0xf6, 0xf9, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x00, 0x10, 0x12, 0x09, 0x1c, 0x20, 0xdb, 0xe1, 0xe2,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfd, 0xfd, 0x9a, 0xbc, 0xc0,
+  0x90, 0xb4, 0xba, 0xef, 0xf4, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xa0, 0xbd, 0xc1, 0x60, 0x90, 0x98, 0x5c, 0x8e, 0x95,
-  0x58, 0x8b, 0x93, 0x54, 0x88, 0x90, 0x50, 0x85, 0x8d, 0x4d, 0x81, 0x8a,
-  0x49, 0x7f, 0x87, 0x46, 0x7c, 0x84, 0x42, 0x79, 0x82, 0x40, 0x76, 0x7f,
-  0x3d, 0x74, 0x7d, 0x38, 0x71, 0x79, 0x35, 0x6e, 0x77, 0x33, 0x6c, 0x75,
-  0x30, 0x69, 0x72, 0x2d, 0x66, 0x70, 0x2b, 0x64, 0x6e, 0x29, 0x63, 0x6c,
-  0x26, 0x60, 0x69, 0x25, 0x5e, 0x68, 0x23, 0x5d, 0x66, 0x20, 0x5a, 0x63,
-  0x1f, 0x58, 0x62, 0x1e, 0x57, 0x60, 0x1c, 0x55, 0x5f, 0x1a, 0x53, 0x5c,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xd8, 0xdb,
+  0x5a, 0x8c, 0x94, 0x53, 0x87, 0x8f, 0x4f, 0x84, 0x8d, 0x4c, 0x81, 0x8a,
+  0x48, 0x7e, 0x86, 0x45, 0x7b, 0x84, 0x42, 0x79, 0x82, 0x3f, 0x76, 0x7f,
+  0x3c, 0x73, 0x7c, 0x38, 0x71, 0x79, 0x35, 0x6e, 0x77, 0x33, 0x6c, 0x75,
+  0x30, 0x69, 0x72, 0x2d, 0x66, 0x70, 0x2b, 0x64, 0x6e, 0x28, 0x62, 0x6b,
+  0x26, 0x60, 0x69, 0x25, 0x5e, 0x68, 0x23, 0x5d, 0x66, 0x21, 0x5a, 0x64,
+  0x1f, 0x58, 0x62, 0x1d, 0x57, 0x5f, 0x1c, 0x55, 0x5f, 0x1a, 0x53, 0x5c,
   0x19, 0x52, 0x5b, 0x17, 0x50, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
   0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x12, 0x48, 0x51, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0x10, 0x44, 0x4c,
-  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x75, 0x92, 0x96, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x11, 0x45, 0x4e, 0xc9, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -9383,85 +9383,21 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x01, 0x12, 0x14, 0x00, 0x0d, 0x0f, 0x80, 0x94, 0x97,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbe, 0xd3, 0xd7,
-  0xc7, 0xda, 0xdc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x13, 0x16, 0x00, 0x0d, 0x0f, 0x27, 0x3f, 0x44, 0xfe, 0xfe, 0xfe,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xed, 0xee, 0x8a, 0xb1, 0xb7,
+  0x85, 0xad, 0xb3, 0xab, 0xc6, 0xca, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xf8, 0xfa, 0xfb, 0x86, 0xab, 0xb1, 0x5a, 0x8d, 0x94,
-  0x57, 0x89, 0x92, 0x52, 0x87, 0x8f, 0x4e, 0x83, 0x8c, 0x4b, 0x80, 0x89,
-  0x48, 0x7e, 0x86, 0x44, 0x7b, 0x83, 0x41, 0x79, 0x81, 0x3f, 0x76, 0x7f,
-  0x3c, 0x73, 0x7c, 0x37, 0x70, 0x79, 0x34, 0x6d, 0x77, 0x32, 0x6b, 0x74,
-  0x2f, 0x69, 0x71, 0x2d, 0x66, 0x70, 0x2a, 0x63, 0x6d, 0x28, 0x62, 0x6b,
-  0x26, 0x5f, 0x68, 0x24, 0x5e, 0x67, 0x22, 0x5c, 0x65, 0x20, 0x5a, 0x63,
-  0x1e, 0x57, 0x61, 0x1d, 0x57, 0x5f, 0x1c, 0x55, 0x5f, 0x1a, 0x53, 0x5c,
-  0x19, 0x52, 0x5b, 0x17, 0x50, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
-  0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
-  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0x10, 0x44, 0x4c,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x4e, 0x72, 0x78,
-  0xf6, 0xf8, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x00, 0x11, 0x13, 0x04, 0x16, 0x19, 0xcb, 0xd4, 0xd6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xbe, 0xc3,
-  0x8d, 0xb3, 0xb9, 0xf1, 0xf6, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xf4, 0xf5, 0x79, 0xa2, 0xa8,
-  0x55, 0x88, 0x91, 0x50, 0x85, 0x8d, 0x4d, 0x82, 0x8b, 0x4a, 0x7f, 0x88,
-  0x46, 0x7d, 0x85, 0x43, 0x7a, 0x83, 0x40, 0x78, 0x81, 0x3d, 0x74, 0x7e,
-  0x3a, 0x72, 0x7b, 0x36, 0x70, 0x78, 0x34, 0x6d, 0x76, 0x31, 0x6b, 0x73,
-  0x2e, 0x68, 0x71, 0x2c, 0x66, 0x6f, 0x2a, 0x63, 0x6d, 0x28, 0x62, 0x6b,
-  0x26, 0x5f, 0x68, 0x24, 0x5e, 0x67, 0x22, 0x5c, 0x65, 0x1f, 0x59, 0x62,
+  0xc1, 0xd4, 0xd7, 0x56, 0x89, 0x91, 0x4d, 0x83, 0x8c, 0x4b, 0x80, 0x89,
+  0x47, 0x7d, 0x86, 0x44, 0x7b, 0x83, 0x40, 0x78, 0x81, 0x3e, 0x75, 0x7e,
+  0x3b, 0x72, 0x7b, 0x37, 0x70, 0x79, 0x34, 0x6d, 0x77, 0x32, 0x6b, 0x74,
+  0x2f, 0x69, 0x71, 0x2c, 0x66, 0x6f, 0x2a, 0x63, 0x6d, 0x27, 0x61, 0x6a,
+  0x26, 0x5f, 0x68, 0x24, 0x5e, 0x67, 0x21, 0x5b, 0x65, 0x20, 0x5a, 0x63,
   0x1e, 0x57, 0x61, 0x1d, 0x57, 0x5f, 0x1b, 0x54, 0x5e, 0x1a, 0x53, 0x5c,
   0x19, 0x52, 0x5b, 0x17, 0x50, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4e, 0x57,
-  0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x13, 0x49, 0x51,
-  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0x10, 0x44, 0x4c,
-  0x10, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x3a, 0x63, 0x6a, 0xe7, 0xec, 0xed,
+  0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x14, 0x4a, 0x52, 0x13, 0x49, 0x51,
+  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0xc9, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -9511,21 +9447,85 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x00, 0x0d, 0x10, 0x1a, 0x32, 0x36, 0xfb, 0xfd, 0xfd,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xf3, 0xf4, 0x8c, 0xb2, 0xb7,
-  0x82, 0xab, 0xb1, 0xac, 0xc7, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x01, 0x13, 0x16, 0x00, 0x0e, 0x10, 0x5d, 0x75, 0x79, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc6, 0xd9, 0xdc, 0x86, 0xae, 0xb4,
+  0x83, 0xab, 0xb2, 0x7f, 0xa8, 0xaf, 0xc6, 0xd8, 0xdb, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed, 0xf2, 0xf3,
-  0x76, 0x9f, 0xa6, 0x4e, 0x84, 0x8c, 0x4c, 0x81, 0x8a, 0x48, 0x7e, 0x87,
-  0x45, 0x7c, 0x85, 0x42, 0x79, 0x82, 0x3f, 0x77, 0x80, 0x3c, 0x74, 0x7d,
-  0x39, 0x71, 0x7a, 0x35, 0x6f, 0x77, 0x33, 0x6c, 0x76, 0x30, 0x6a, 0x73,
-  0x2e, 0x68, 0x71, 0x2b, 0x65, 0x6f, 0x29, 0x63, 0x6d, 0x27, 0x61, 0x6a,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xc8, 0xd9, 0xdc, 0x59, 0x8a, 0x93, 0x49, 0x7f, 0x88,
+  0x46, 0x7d, 0x85, 0x42, 0x79, 0x82, 0x40, 0x77, 0x80, 0x3d, 0x74, 0x7e,
+  0x39, 0x71, 0x7a, 0x35, 0x6f, 0x77, 0x34, 0x6d, 0x76, 0x31, 0x6b, 0x73,
+  0x2e, 0x68, 0x71, 0x2c, 0x66, 0x6f, 0x2a, 0x63, 0x6d, 0x27, 0x61, 0x6a,
+  0x25, 0x5e, 0x68, 0x24, 0x5e, 0x67, 0x21, 0x5b, 0x65, 0x20, 0x5a, 0x63,
+  0x1e, 0x57, 0x61, 0x1c, 0x56, 0x5f, 0x1b, 0x54, 0x5e, 0x1a, 0x53, 0x5c,
+  0x18, 0x51, 0x5a, 0x17, 0x50, 0x58, 0x16, 0x4f, 0x58, 0x16, 0x4e, 0x57,
+  0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x13, 0x49, 0x51,
+  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0xc8, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
+  0x01, 0x12, 0x15, 0x03, 0x14, 0x17, 0xbb, 0xc8, 0xc9, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0xc0, 0xc4, 0x84, 0xac, 0xb2,
+  0x80, 0xa9, 0xb0, 0x7c, 0xa6, 0xad, 0x7d, 0xa8, 0xae, 0xda, 0xe6, 0xe8,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xe7, 0xe9, 0x68, 0x94, 0x9d,
+  0x44, 0x7b, 0x84, 0x41, 0x79, 0x81, 0x3f, 0x77, 0x80, 0x3b, 0x73, 0x7c,
+  0x38, 0x70, 0x7a, 0x34, 0x6e, 0x77, 0x32, 0x6b, 0x75, 0x30, 0x6a, 0x73,
+  0x2d, 0x67, 0x70, 0x2a, 0x64, 0x6e, 0x28, 0x62, 0x6c, 0x26, 0x61, 0x6a,
   0x25, 0x5e, 0x68, 0x23, 0x5d, 0x66, 0x20, 0x5b, 0x64, 0x1f, 0x59, 0x62,
-  0x1e, 0x57, 0x61, 0x1c, 0x56, 0x5f, 0x1b, 0x54, 0x5e, 0x19, 0x52, 0x5c,
+  0x1d, 0x57, 0x60, 0x1c, 0x56, 0x5f, 0x1a, 0x54, 0x5d, 0x19, 0x52, 0x5c,
   0x18, 0x51, 0x5a, 0x17, 0x50, 0x58, 0x16, 0x4f, 0x58, 0x15, 0x4d, 0x56,
   0x15, 0x4c, 0x55, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x13, 0x49, 0x51,
-  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0x10, 0x44, 0x4c,
-  0x10, 0x43, 0x4b, 0x38, 0x62, 0x68, 0xdf, 0xe6, 0xe7, 0xff, 0xff, 0xff,
+  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x2d, 0x5b, 0x63, 0xe2, 0xe8, 0xe9,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -9575,148 +9575,20 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x02, 0x13, 0x16, 0x00, 0x0d, 0x0f, 0x47, 0x61, 0x65, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xe0, 0xe2, 0x83, 0xab, 0xb2,
-  0x7f, 0xa9, 0xaf, 0x7b, 0xa6, 0xad, 0xcb, 0xdb, 0xde, 0xff, 0xff, 0xff,
+  0x00, 0x0f, 0x11, 0x1a, 0x32, 0x36, 0xf8, 0xfa, 0xfa, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xe6, 0xef, 0xf0, 0x87, 0xaf, 0xb5, 0x81, 0xaa, 0xb1,
+  0x7d, 0xa8, 0xae, 0x79, 0xa5, 0xab, 0x76, 0xa2, 0xa9, 0x81, 0xa9, 0xaf,
+  0xe8, 0xef, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xf1, 0xf5, 0xf6, 0x7d, 0xa5, 0xab, 0x4b, 0x81, 0x8a, 0x46, 0x7d, 0x86,
-  0x43, 0x7b, 0x83, 0x40, 0x78, 0x81, 0x3e, 0x76, 0x7f, 0x3b, 0x73, 0x7c,
-  0x38, 0x70, 0x7a, 0x34, 0x6e, 0x77, 0x32, 0x6b, 0x75, 0x2f, 0x69, 0x72,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf7, 0xf7,
+  0x91, 0xb2, 0xb7, 0x42, 0x79, 0x81, 0x3d, 0x75, 0x7e, 0x3a, 0x72, 0x7c,
+  0x37, 0x70, 0x79, 0x34, 0x6e, 0x76, 0x31, 0x6b, 0x74, 0x2e, 0x69, 0x72,
   0x2c, 0x67, 0x6f, 0x2a, 0x64, 0x6e, 0x28, 0x62, 0x6c, 0x26, 0x60, 0x69,
-  0x24, 0x5e, 0x67, 0x23, 0x5d, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x58, 0x62,
-  0x1d, 0x57, 0x60, 0x1c, 0x56, 0x5f, 0x1a, 0x54, 0x5d, 0x19, 0x52, 0x5c,
-  0x18, 0x51, 0x5a, 0x16, 0x4f, 0x58, 0x16, 0x4f, 0x58, 0x15, 0x4d, 0x56,
-  0x14, 0x4c, 0x54, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x13, 0x49, 0x51,
-  0x11, 0x47, 0x50, 0x11, 0x46, 0x4f, 0x10, 0x44, 0x4d, 0x10, 0x44, 0x4c,
-  0x45, 0x6d, 0x73, 0xe4, 0xe9, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x01, 0x13, 0x16, 0x00, 0x11, 0x14, 0x9b, 0xac, 0xae, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa9, 0xc5, 0xca, 0x7f, 0xa9, 0xaf,
-  0x7c, 0xa7, 0xae, 0x78, 0xa4, 0xab, 0x7e, 0xa7, 0xaf, 0xe1, 0xea, 0xec,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfc, 0x98, 0xb7, 0xbc, 0x44, 0x7b, 0x85,
-  0x42, 0x7a, 0x83, 0x3f, 0x77, 0x80, 0x3c, 0x75, 0x7e, 0x39, 0x72, 0x7b,
-  0x36, 0x6f, 0x78, 0x33, 0x6d, 0x76, 0x31, 0x6b, 0x74, 0x2e, 0x69, 0x72,
-  0x2b, 0x66, 0x6f, 0x29, 0x64, 0x6e, 0x27, 0x61, 0x6b, 0x26, 0x60, 0x69,
-  0x24, 0x5e, 0x67, 0x22, 0x5c, 0x66, 0x1f, 0x5a, 0x63, 0x1e, 0x58, 0x62,
+  0x24, 0x5e, 0x67, 0x22, 0x5c, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x58, 0x62,
   0x1d, 0x57, 0x60, 0x1b, 0x55, 0x5e, 0x1a, 0x54, 0x5d, 0x19, 0x52, 0x5c,
   0x18, 0x51, 0x5a, 0x17, 0x50, 0x58, 0x16, 0x4f, 0x58, 0x15, 0x4d, 0x56,
   0x14, 0x4c, 0x54, 0x14, 0x4b, 0x53, 0x13, 0x49, 0x52, 0x12, 0x48, 0x50,
-  0x11, 0x47, 0x50, 0x10, 0x45, 0x4e, 0x10, 0x44, 0x4d, 0x67, 0x88, 0x8d,
-  0xf2, 0xf5, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x00, 0x11, 0x12, 0x0e, 0x25, 0x28, 0xe6, 0xec, 0xec, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xf0, 0xf5, 0xf6, 0x8a, 0xb1, 0xb7, 0x7c, 0xa7, 0xae,
-  0x78, 0xa5, 0xab, 0x75, 0xa1, 0xa9, 0x72, 0xa0, 0xa7, 0x86, 0xad, 0xb3,
-  0xf2, 0xf6, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xd5, 0xd8,
-  0x57, 0x89, 0x91, 0x3e, 0x76, 0x7f, 0x3b, 0x74, 0x7d, 0x38, 0x71, 0x7a,
-  0x35, 0x6e, 0x78, 0x32, 0x6c, 0x75, 0x2f, 0x69, 0x73, 0x2d, 0x68, 0x71,
-  0x2a, 0x65, 0x6e, 0x28, 0x63, 0x6d, 0x26, 0x61, 0x6b, 0x25, 0x5f, 0x69,
-  0x23, 0x5d, 0x66, 0x22, 0x5c, 0x66, 0x1f, 0x5a, 0x63, 0x1e, 0x58, 0x62,
-  0x1c, 0x56, 0x60, 0x1b, 0x55, 0x5e, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
-  0x17, 0x51, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x15, 0x4d, 0x56,
-  0x14, 0x4c, 0x54, 0x13, 0x4a, 0x53, 0x13, 0x49, 0x52, 0x12, 0x48, 0x50,
-  0x11, 0x47, 0x50, 0x22, 0x53, 0x5b, 0xa0, 0xb5, 0xb8, 0xff, 0xff, 0xff,
+  0x11, 0x47, 0x50, 0x61, 0x84, 0x8a, 0xe5, 0xea, 0xeb, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -9767,20 +9639,20 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x02, 0x15, 0x18,
-  0x00, 0x0e, 0x10, 0x3a, 0x54, 0x59, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xcd, 0xde, 0xe1, 0x7c, 0xa8, 0xae, 0x79, 0xa5, 0xac,
-  0x76, 0xa3, 0xaa, 0x72, 0xa0, 0xa7, 0x6e, 0x9d, 0xa4, 0x6c, 0x9b, 0xa2,
-  0x92, 0xb5, 0xba, 0xfa, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x00, 0x0e, 0x11, 0x53, 0x6c, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xc1, 0xd6, 0xd9, 0x82, 0xab, 0xb2, 0x7e, 0xa8, 0xaf,
+  0x7a, 0xa6, 0xad, 0x77, 0xa3, 0xaa, 0x73, 0xa0, 0xa7, 0x6f, 0x9d, 0xa4,
+  0x85, 0xac, 0xb2, 0xed, 0xf3, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xee, 0xf3, 0xf4, 0x91, 0xb1, 0xb6, 0x41, 0x78, 0x81, 0x36, 0x70, 0x79,
-  0x33, 0x6d, 0x76, 0x31, 0x6c, 0x74, 0x2e, 0x69, 0x72, 0x2c, 0x67, 0x70,
-  0x29, 0x65, 0x6e, 0x27, 0x62, 0x6c, 0x26, 0x60, 0x6a, 0x24, 0x5f, 0x68,
-  0x22, 0x5c, 0x66, 0x21, 0x5c, 0x65, 0x1e, 0x59, 0x63, 0x1d, 0x58, 0x61,
-  0x1b, 0x55, 0x5f, 0x1a, 0x55, 0x5d, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
-  0x17, 0x51, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x14, 0x4d, 0x55,
-  0x14, 0x4c, 0x54, 0x13, 0x4a, 0x53, 0x13, 0x49, 0x52, 0x14, 0x49, 0x51,
-  0x63, 0x86, 0x8c, 0xde, 0xe5, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xcd, 0xdb, 0xde, 0x66, 0x93, 0x9a, 0x39, 0x72, 0x7b,
+  0x36, 0x6f, 0x78, 0x33, 0x6d, 0x76, 0x30, 0x6a, 0x74, 0x2d, 0x68, 0x71,
+  0x2b, 0x66, 0x6f, 0x28, 0x63, 0x6d, 0x27, 0x61, 0x6b, 0x26, 0x61, 0x6a,
+  0x24, 0x5e, 0x67, 0x22, 0x5c, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x58, 0x62,
+  0x1c, 0x56, 0x60, 0x1b, 0x55, 0x5e, 0x1a, 0x54, 0x5d, 0x18, 0x51, 0x5b,
+  0x17, 0x51, 0x59, 0x17, 0x50, 0x58, 0x16, 0x4f, 0x58, 0x15, 0x4d, 0x56,
+  0x14, 0x4c, 0x54, 0x13, 0x4a, 0x53, 0x13, 0x49, 0x52, 0x3a, 0x67, 0x6e,
+  0xb2, 0xc4, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0xbc, 0xbf,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -9831,22 +9703,86 @@
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
   0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x01, 0x14, 0x17,
-  0x00, 0x12, 0x15, 0x91, 0xa4, 0xa7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0x9f, 0xc0, 0xc5, 0x79, 0xa6, 0xad, 0x76, 0xa3, 0xaa,
-  0x73, 0xa1, 0xa8, 0x6f, 0x9e, 0xa5, 0x6c, 0x9b, 0xa3, 0x68, 0x98, 0xa0,
-  0x64, 0x96, 0x9d, 0x98, 0xb9, 0xbe, 0xfc, 0xfd, 0xfd, 0xff, 0xff, 0xff,
+  0x03, 0x15, 0x19, 0xb8, 0xc4, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfb, 0xfc, 0xfd, 0x97, 0xba, 0xbf, 0x7e, 0xa9, 0xaf, 0x7a, 0xa6, 0xad,
+  0x78, 0xa4, 0xab, 0x74, 0xa1, 0xa8, 0x70, 0x9e, 0xa6, 0x6c, 0x9b, 0xa3,
+  0x69, 0x99, 0xa0, 0x81, 0xa9, 0xb0, 0xec, 0xf2, 0xf3, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xe7, 0xe8, 0x82, 0xa6, 0xac,
-  0x3d, 0x73, 0x7c, 0x2f, 0x6a, 0x73, 0x2d, 0x68, 0x72, 0x2b, 0x67, 0x70,
-  0x29, 0x65, 0x6e, 0x26, 0x62, 0x6c, 0x25, 0x5f, 0x69, 0x24, 0x5f, 0x68,
-  0x22, 0x5c, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x59, 0x63, 0x1d, 0x58, 0x61,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfc, 0xb9, 0xcd, 0xd1,
+  0x5f, 0x8d, 0x94, 0x33, 0x6d, 0x76, 0x2f, 0x69, 0x73, 0x2c, 0x67, 0x70,
+  0x2a, 0x65, 0x6e, 0x27, 0x62, 0x6c, 0x26, 0x60, 0x6a, 0x24, 0x5f, 0x68,
+  0x23, 0x5d, 0x66, 0x21, 0x5c, 0x65, 0x1f, 0x5a, 0x63, 0x1d, 0x58, 0x61,
+  0x1c, 0x56, 0x60, 0x1b, 0x55, 0x5e, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
+  0x17, 0x51, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x15, 0x4d, 0x56,
+  0x14, 0x4c, 0x54, 0x40, 0x6d, 0x74, 0xa4, 0xb9, 0xbd, 0xf7, 0xf9, 0xf9,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xbe, 0xc1,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x00, 0x10, 0x13,
+  0x1f, 0x39, 0x3d, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xda, 0xe7, 0xe9, 0x7e, 0xa9, 0xb0, 0x7b, 0xa7, 0xae, 0x78, 0xa4, 0xab,
+  0x74, 0xa1, 0xa9, 0x71, 0x9f, 0xa6, 0x6d, 0x9c, 0xa4, 0x6a, 0x99, 0xa1,
+  0x66, 0x97, 0x9f, 0x63, 0x94, 0x9c, 0x79, 0xa4, 0xa9, 0xe4, 0xed, 0xee,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfc, 0xfd, 0xfd, 0xc9, 0xd8, 0xda, 0x81, 0xa4, 0xaa, 0x42, 0x78, 0x80,
+  0x29, 0x65, 0x6e, 0x27, 0x62, 0x6c, 0x25, 0x5f, 0x69, 0x24, 0x5f, 0x68,
+  0x23, 0x5d, 0x66, 0x20, 0x5b, 0x64, 0x1e, 0x59, 0x63, 0x1d, 0x58, 0x61,
   0x1b, 0x55, 0x5f, 0x1a, 0x55, 0x5d, 0x19, 0x53, 0x5d, 0x18, 0x51, 0x5b,
-  0x17, 0x51, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x14, 0x4d, 0x55,
-  0x14, 0x4c, 0x54, 0x17, 0x4d, 0x56, 0x59, 0x7f, 0x85, 0xc5, 0xd3, 0xd4,
+  0x17, 0x51, 0x59, 0x17, 0x50, 0x59, 0x31, 0x63, 0x6b, 0x70, 0x93, 0x98,
+  0xbe, 0xce, 0xd0, 0xfa, 0xfb, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0xc0, 0xc2,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb4, 0xc3, 0xc5, 0x54, 0x75, 0x7b,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -9894,23 +9830,23 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x00, 0x11, 0x14,
-  0x10, 0x28, 0x2c, 0xeb, 0xee, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xe6, 0xee, 0xef, 0x7d, 0xa9, 0xb0, 0x76, 0xa3, 0xaa, 0x73, 0xa1, 0xa8,
-  0x6f, 0x9e, 0xa6, 0x6c, 0x9c, 0xa3, 0x6a, 0x9a, 0xa2, 0x66, 0x97, 0x9f,
-  0x62, 0x94, 0x9c, 0x5f, 0x92, 0x9a, 0x94, 0xb6, 0xbb, 0xfb, 0xfc, 0xfd,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x16, 0x1a, 0x00, 0x10, 0x13,
+  0x6a, 0x82, 0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xc6, 0xcb, 0x7a, 0xa7, 0xae, 0x78, 0xa4, 0xab, 0x75, 0xa2, 0xa9,
+  0x71, 0xa0, 0xa7, 0x6e, 0x9d, 0xa4, 0x6b, 0x9b, 0xa2, 0x68, 0x98, 0xa0,
+  0x64, 0x96, 0x9d, 0x60, 0x92, 0x9a, 0x5d, 0x91, 0x98, 0x69, 0x98, 0xa0,
+  0xd1, 0xdf, 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xf7, 0xf8,
+  0xc8, 0xd7, 0xda, 0x98, 0xb5, 0xb9, 0x72, 0x97, 0x9e, 0x52, 0x80, 0x87,
+  0x3b, 0x6f, 0x77, 0x2d, 0x65, 0x6d, 0x29, 0x61, 0x6a, 0x27, 0x5f, 0x68,
+  0x29, 0x60, 0x69, 0x39, 0x6c, 0x73, 0x4f, 0x7b, 0x83, 0x6e, 0x92, 0x98,
+  0x95, 0xb0, 0xb3, 0xc7, 0xd5, 0xd7, 0xf4, 0xf7, 0xf7, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xe2, 0xea, 0xec, 0x99, 0xb6, 0xba, 0x53, 0x83, 0x8b, 0x2c, 0x67, 0x70,
-  0x28, 0x64, 0x6d, 0x26, 0x61, 0x6b, 0x25, 0x5f, 0x69, 0x24, 0x5f, 0x68,
-  0x21, 0x5c, 0x65, 0x20, 0x5b, 0x64, 0x1d, 0x59, 0x62, 0x1c, 0x57, 0x61,
-  0x1b, 0x55, 0x5f, 0x19, 0x54, 0x5d, 0x18, 0x52, 0x5c, 0x17, 0x51, 0x5a,
-  0x17, 0x50, 0x59, 0x16, 0x4f, 0x58, 0x15, 0x4e, 0x57, 0x32, 0x64, 0x6b,
-  0x7a, 0x99, 0x9e, 0xd0, 0xdb, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xee, 0xf1, 0xf2, 0x8d, 0xa3, 0xa7,
+  0xff, 0xff, 0xff, 0x9d, 0xb1, 0xb4, 0x13, 0x42, 0x49, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -9958,23 +9894,23 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x02, 0x17, 0x1a, 0x00, 0x0f, 0x12,
-  0x4b, 0x65, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xb6, 0xcf, 0xd3, 0x76, 0xa4, 0xab, 0x72, 0xa1, 0xa8, 0x6f, 0x9e, 0xa6,
-  0x6c, 0x9c, 0xa4, 0x69, 0x99, 0xa1, 0x66, 0x97, 0x9f, 0x63, 0x95, 0x9d,
-  0x5f, 0x92, 0x9a, 0x5c, 0x90, 0x98, 0x58, 0x8d, 0x95, 0x88, 0xae, 0xb3,
-  0xf3, 0xf7, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfc, 0xd5, 0xe1, 0xe3,
-  0x9d, 0xb9, 0xbd, 0x70, 0x97, 0x9d, 0x4a, 0x7b, 0x83, 0x2d, 0x65, 0x6f,
-  0x24, 0x5f, 0x67, 0x1f, 0x5a, 0x64, 0x1d, 0x59, 0x62, 0x1b, 0x56, 0x60,
-  0x1a, 0x55, 0x5e, 0x1c, 0x56, 0x5f, 0x20, 0x58, 0x62, 0x37, 0x69, 0x71,
-  0x5c, 0x84, 0x8a, 0x89, 0xa5, 0xaa, 0xc2, 0xd1, 0xd4, 0xf5, 0xf7, 0xf8,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x00, 0x14, 0x18, 0x0a, 0x21, 0x25,
+  0xdb, 0xe1, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0xf0, 0xf1,
+  0x80, 0xab, 0xb1, 0x78, 0xa5, 0xac, 0x74, 0xa2, 0xa9, 0x71, 0xa0, 0xa7,
+  0x6e, 0x9e, 0xa5, 0x6b, 0x9b, 0xa2, 0x67, 0x98, 0xa0, 0x65, 0x96, 0x9e,
+  0x61, 0x94, 0x9b, 0x5d, 0x91, 0x99, 0x5a, 0x8f, 0x96, 0x57, 0x8b, 0x94,
+  0x58, 0x8c, 0x94, 0xae, 0xc7, 0xcb, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xe7, 0xec, 0xed, 0x4a, 0x6e, 0x74, 0x11, 0x3f, 0x47,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfc, 0xfd,
+  0xf5, 0xf7, 0xf8, 0xee, 0xf3, 0xf3, 0xea, 0xef, 0xf0, 0xea, 0xef, 0xf0,
+  0xf0, 0xf4, 0xf4, 0xf5, 0xf8, 0xf8, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xfb, 0xfb,
+  0x7b, 0x96, 0x9a, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
@@ -10022,76 +9958,12 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x00, 0x15, 0x19, 0x04, 0x18, 0x1b,
-  0xb6, 0xc3, 0xc4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xf8, 0xf9,
-  0x85, 0xad, 0xb4, 0x72, 0xa1, 0xa9, 0x6f, 0x9f, 0xa6, 0x6c, 0x9c, 0xa4,
-  0x69, 0x9a, 0xa2, 0x66, 0x97, 0x9f, 0x63, 0x96, 0x9e, 0x60, 0x92, 0x9b,
-  0x5c, 0x91, 0x98, 0x59, 0x8e, 0x96, 0x56, 0x8b, 0x93, 0x53, 0x89, 0x92,
-  0x74, 0x9f, 0xa6, 0xe4, 0xec, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfb, 0xfb, 0xeb, 0xf0, 0xf1,
-  0xd6, 0xe1, 0xe2, 0xc4, 0xd4, 0xd6, 0xba, 0xcc, 0xcf, 0xb8, 0xcb, 0xce,
-  0xc0, 0xd0, 0xd3, 0xce, 0xdb, 0xdd, 0xe6, 0xec, 0xed, 0xf5, 0xf7, 0xf8,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xcf, 0xd9, 0xda, 0x34, 0x5d, 0x63, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x00, 0x11, 0x14, 0x26, 0x41, 0x46,
-  0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xda, 0xdd,
-  0x71, 0xa1, 0xa8, 0x6e, 0x9f, 0xa6, 0x6c, 0x9c, 0xa4, 0x69, 0x9a, 0xa2,
-  0x66, 0x98, 0xa0, 0x62, 0x95, 0x9d, 0x60, 0x94, 0x9c, 0x5d, 0x91, 0x99,
-  0x59, 0x8f, 0x96, 0x57, 0x8c, 0x95, 0x54, 0x8a, 0x92, 0x50, 0x87, 0x90,
-  0x4d, 0x84, 0x8d, 0x5b, 0x8d, 0x95, 0xc3, 0xd5, 0xd8, 0xff, 0xff, 0xff,
+  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1c, 0x00, 0x11, 0x14, 0x40, 0x5c, 0x5f,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb5, 0xce, 0xd2,
+  0x77, 0xa4, 0xab, 0x74, 0xa3, 0xaa, 0x71, 0xa0, 0xa7, 0x6e, 0x9e, 0xa5,
+  0x6b, 0x9b, 0xa3, 0x68, 0x99, 0xa0, 0x65, 0x97, 0x9f, 0x61, 0x94, 0x9c,
+  0x5e, 0x92, 0x99, 0x5b, 0x8f, 0x98, 0x57, 0x8d, 0x95, 0x54, 0x89, 0x92,
+  0x51, 0x87, 0x90, 0x4e, 0x85, 0x8d, 0x7e, 0xa5, 0xac, 0xe4, 0xed, 0xee,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -10101,71 +9973,7 @@
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xb3, 0xb6,
-  0x1a, 0x4a, 0x50, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x02, 0x18, 0x1b, 0x00, 0x14, 0x17, 0x84, 0x98, 0x9c,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfc, 0xfd, 0x8c, 0xb3, 0xb9,
-  0x6d, 0x9e, 0xa6, 0x6b, 0x9d, 0xa4, 0x68, 0x9a, 0xa2, 0x65, 0x98, 0x9f,
-  0x62, 0x96, 0x9e, 0x60, 0x93, 0x9b, 0x5d, 0x91, 0x9a, 0x5a, 0x8f, 0x97,
-  0x57, 0x8d, 0x95, 0x54, 0x8a, 0x93, 0x51, 0x88, 0x90, 0x4e, 0x86, 0x8f,
-  0x4b, 0x83, 0x8c, 0x49, 0x81, 0x8a, 0x46, 0x7e, 0x87, 0x8d, 0xaf, 0xb5,
-  0xef, 0xf4, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xe2, 0xe8, 0xe9, 0x5d, 0x7f, 0x84, 0x0d, 0x3f, 0x47,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xe3, 0xe4, 0x4a, 0x6f, 0x75,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -10214,13 +10022,13 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x1a, 0x1e, 0x00, 0x14, 0x17, 0x16, 0x31, 0x34, 0xf2, 0xf6, 0xf6,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xdf, 0xe1, 0x6c, 0x9e, 0xa6,
-  0x6a, 0x9c, 0xa4, 0x67, 0x9a, 0xa2, 0x64, 0x98, 0x9f, 0x61, 0x95, 0x9d,
-  0x60, 0x94, 0x9c, 0x5d, 0x91, 0x9a, 0x5a, 0x8f, 0x98, 0x57, 0x8d, 0x95,
-  0x54, 0x8b, 0x93, 0x51, 0x88, 0x91, 0x4e, 0x86, 0x8f, 0x4b, 0x84, 0x8d,
-  0x49, 0x81, 0x8a, 0x46, 0x7f, 0x88, 0x43, 0x7c, 0x85, 0x40, 0x7b, 0x83,
-  0x55, 0x88, 0x91, 0xb7, 0xcc, 0xd0, 0xfc, 0xfd, 0xfd, 0xff, 0xff, 0xff,
+  0x02, 0x1a, 0x1e, 0x00, 0x17, 0x1b, 0x03, 0x19, 0x1c, 0xae, 0xbd, 0xbf,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf5, 0xf6, 0x81, 0xab, 0xb2,
+  0x73, 0xa2, 0xa9, 0x70, 0xa0, 0xa7, 0x6d, 0x9e, 0xa5, 0x6b, 0x9b, 0xa3,
+  0x68, 0x99, 0xa1, 0x64, 0x96, 0x9e, 0x62, 0x95, 0x9d, 0x5f, 0x92, 0x9a,
+  0x5b, 0x90, 0x98, 0x58, 0x8d, 0x96, 0x55, 0x8b, 0x93, 0x52, 0x88, 0x91,
+  0x4e, 0x85, 0x8e, 0x4c, 0x84, 0x8c, 0x49, 0x80, 0x89, 0x54, 0x88, 0x90,
+  0xac, 0xc5, 0xc9, 0xfa, 0xfb, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -10228,8 +10036,8 @@
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf8, 0xf8,
-  0x95, 0xac, 0xaf, 0x22, 0x51, 0x58, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfb, 0xfc, 0xfc, 0x9a, 0xaf, 0xb3, 0x1e, 0x4d, 0x55, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
@@ -10278,21 +10086,85 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x02, 0x19, 0x1d, 0x00, 0x13, 0x17, 0x6e, 0x85, 0x89, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xfc, 0xfd, 0xfd, 0x8c, 0xb3, 0xb9, 0x69, 0x9b, 0xa4,
-  0x66, 0x99, 0xa1, 0x64, 0x98, 0xa0, 0x61, 0x96, 0x9e, 0x5f, 0x93, 0x9b,
-  0x5c, 0x91, 0x9a, 0x59, 0x8f, 0x97, 0x57, 0x8e, 0x96, 0x55, 0x8b, 0x94,
-  0x51, 0x89, 0x91, 0x4e, 0x86, 0x8f, 0x4b, 0x85, 0x8d, 0x49, 0x82, 0x8b,
-  0x46, 0x7f, 0x89, 0x44, 0x7e, 0x87, 0x41, 0x7b, 0x84, 0x3e, 0x79, 0x82,
-  0x3c, 0x76, 0x80, 0x39, 0x75, 0x7e, 0x63, 0x92, 0x9a, 0xc0, 0xd3, 0xd6,
-  0xfc, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x1a, 0x1e, 0x00, 0x13, 0x16, 0x29, 0x46, 0x4b, 0xfe, 0xfe, 0xfe,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb9, 0xd1, 0xd5, 0x72, 0xa1, 0xa9,
+  0x6f, 0xa0, 0xa7, 0x6c, 0x9e, 0xa5, 0x6a, 0x9b, 0xa3, 0x67, 0x99, 0xa1,
+  0x64, 0x97, 0x9f, 0x61, 0x94, 0x9c, 0x5f, 0x93, 0x9b, 0x5c, 0x90, 0x98,
+  0x58, 0x8e, 0x96, 0x56, 0x8b, 0x94, 0x52, 0x89, 0x91, 0x4f, 0x86, 0x8f,
+  0x4c, 0x84, 0x8d, 0x4a, 0x82, 0x8a, 0x47, 0x7f, 0x88, 0x44, 0x7d, 0x86,
+  0x41, 0x7a, 0x84, 0x66, 0x94, 0x9b, 0xc9, 0xd9, 0xdc, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xf7, 0xf8, 0xf9, 0xa5, 0xb9, 0xbc, 0x37, 0x63, 0x69,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc2, 0xcf, 0xd1,
+  0x47, 0x6e, 0x75, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
+  0x02, 0x19, 0x1d, 0x01, 0x18, 0x1b, 0x96, 0xa9, 0xac, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xef, 0xf5, 0xf5, 0x7e, 0xaa, 0xb1, 0x6e, 0x9f, 0xa7,
+  0x6c, 0x9d, 0xa5, 0x69, 0x9b, 0xa3, 0x66, 0x99, 0xa1, 0x64, 0x97, 0x9f,
+  0x61, 0x95, 0x9d, 0x5e, 0x92, 0x9a, 0x5c, 0x91, 0x99, 0x59, 0x8e, 0x97,
+  0x56, 0x8c, 0x94, 0x53, 0x8a, 0x92, 0x50, 0x88, 0x90, 0x4d, 0x85, 0x8e,
+  0x4a, 0x82, 0x8b, 0x48, 0x80, 0x89, 0x45, 0x7e, 0x86, 0x42, 0x7c, 0x85,
+  0x3f, 0x79, 0x83, 0x3c, 0x77, 0x80, 0x3a, 0x75, 0x7f, 0x73, 0x9c, 0xa3,
+  0xcd, 0xdc, 0xde, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xfe, 0xfe, 0xfe, 0xc4, 0xd1, 0xd3, 0x58, 0x7d, 0x83, 0x11, 0x45, 0x4d,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -10342,21 +10214,21 @@
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
   0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x00, 0x16, 0x19, 0x11, 0x2c, 0x30, 0xe9, 0xed, 0xee, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xc9, 0xdc, 0xdf, 0x68, 0x9b, 0xa3, 0x65, 0x99, 0xa1,
-  0x63, 0x98, 0xa0, 0x60, 0x96, 0x9e, 0x5e, 0x93, 0x9b, 0x5b, 0x91, 0x99,
-  0x59, 0x8f, 0x98, 0x56, 0x8d, 0x96, 0x55, 0x8c, 0x94, 0x52, 0x89, 0x92,
-  0x4e, 0x87, 0x8f, 0x4b, 0x85, 0x8e, 0x49, 0x83, 0x8b, 0x47, 0x81, 0x8a,
-  0x44, 0x7e, 0x87, 0x41, 0x7c, 0x85, 0x3e, 0x79, 0x82, 0x3d, 0x78, 0x81,
-  0x3a, 0x75, 0x7f, 0x37, 0x74, 0x7d, 0x34, 0x71, 0x7b, 0x33, 0x6f, 0x79,
-  0x5d, 0x8d, 0x94, 0xad, 0xc5, 0xc9, 0xee, 0xf3, 0xf4, 0xff, 0xff, 0xff,
+  0x00, 0x14, 0x18, 0x23, 0x40, 0x45, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xb3, 0xcd, 0xd1, 0x6d, 0x9f, 0xa6, 0x6b, 0x9d, 0xa5,
+  0x69, 0x9b, 0xa3, 0x66, 0x99, 0xa1, 0x63, 0x97, 0x9f, 0x60, 0x94, 0x9d,
+  0x5e, 0x93, 0x9b, 0x5c, 0x91, 0x99, 0x59, 0x8f, 0x97, 0x56, 0x8c, 0x95,
+  0x53, 0x8a, 0x92, 0x50, 0x88, 0x91, 0x4d, 0x86, 0x8e, 0x4b, 0x83, 0x8c,
+  0x48, 0x80, 0x8a, 0x45, 0x7f, 0x87, 0x42, 0x7c, 0x85, 0x3f, 0x7a, 0x83,
+  0x3e, 0x78, 0x82, 0x3a, 0x76, 0x7f, 0x37, 0x73, 0x7d, 0x35, 0x71, 0x7b,
+  0x35, 0x70, 0x79, 0x66, 0x92, 0x99, 0xb4, 0xca, 0xcd, 0xf1, 0xf5, 0xf6,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xe9, 0xea,
-  0x92, 0xab, 0xaf, 0x34, 0x61, 0x69, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xf1, 0xf1, 0xa4, 0xb9, 0xbc,
+  0x4a, 0x73, 0x7a, 0x12, 0x46, 0x4f, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
@@ -10405,21 +10277,21 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1b, 0x1f,
-  0x00, 0x14, 0x18, 0x69, 0x81, 0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xf7, 0xfa, 0xfa, 0x82, 0xad, 0xb3, 0x64, 0x99, 0xa1, 0x61, 0x96, 0x9f,
-  0x60, 0x95, 0x9d, 0x5d, 0x93, 0x9c, 0x5b, 0x91, 0x9a, 0x58, 0x8f, 0x97,
-  0x55, 0x8d, 0x96, 0x54, 0x8b, 0x94, 0x51, 0x89, 0x92, 0x4f, 0x87, 0x90,
-  0x4b, 0x85, 0x8e, 0x49, 0x83, 0x8c, 0x47, 0x81, 0x8a, 0x44, 0x7f, 0x88,
-  0x41, 0x7c, 0x86, 0x3f, 0x7b, 0x84, 0x3d, 0x78, 0x81, 0x3b, 0x77, 0x80,
-  0x38, 0x74, 0x7e, 0x35, 0x73, 0x7c, 0x33, 0x70, 0x7a, 0x31, 0x6e, 0x78,
-  0x2f, 0x6c, 0x76, 0x2d, 0x6a, 0x74, 0x3e, 0x77, 0x80, 0x7b, 0xa1, 0xa7,
-  0xbb, 0xce, 0xd2, 0xee, 0xf3, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x02, 0x1a, 0x1e,
+  0x01, 0x18, 0x1c, 0x94, 0xa7, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xe8, 0xf0, 0xf1, 0x74, 0xa3, 0xab, 0x6a, 0x9d, 0xa4, 0x67, 0x9a, 0xa2,
+  0x65, 0x99, 0xa1, 0x62, 0x97, 0x9f, 0x60, 0x94, 0x9d, 0x5d, 0x92, 0x9a,
+  0x5b, 0x91, 0x99, 0x58, 0x8e, 0x97, 0x55, 0x8c, 0x95, 0x54, 0x8a, 0x93,
+  0x50, 0x88, 0x91, 0x4d, 0x86, 0x8f, 0x4b, 0x84, 0x8c, 0x48, 0x81, 0x8b,
+  0x45, 0x7f, 0x88, 0x43, 0x7d, 0x86, 0x40, 0x7b, 0x83, 0x3e, 0x79, 0x82,
+  0x3b, 0x76, 0x80, 0x38, 0x75, 0x7e, 0x35, 0x72, 0x7c, 0x33, 0x70, 0x7a,
+  0x32, 0x6e, 0x78, 0x2f, 0x6b, 0x75, 0x2d, 0x6a, 0x74, 0x40, 0x77, 0x80,
+  0x7b, 0xa1, 0xa7, 0xb6, 0xcb, 0xce, 0xe6, 0xed, 0xee, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xe2, 0xe9, 0xea, 0xa9, 0xbd, 0xc0, 0x5e, 0x83, 0x89, 0x1e, 0x51, 0x59,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xde, 0xe6, 0xe7,
+  0xa9, 0xbd, 0xc0, 0x65, 0x89, 0x8e, 0x25, 0x56, 0x5e, 0x11, 0x47, 0x4f,
   0x10, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
@@ -10469,21 +10341,85 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x00, 0x17, 0x1b,
-  0x13, 0x2f, 0x34, 0xea, 0xef, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xb8, 0xd1, 0xd4, 0x63, 0x98, 0xa0, 0x60, 0x96, 0x9f, 0x5e, 0x94, 0x9d,
-  0x5c, 0x93, 0x9b, 0x59, 0x91, 0x99, 0x57, 0x8f, 0x98, 0x55, 0x8d, 0x96,
-  0x53, 0x8b, 0x94, 0x50, 0x89, 0x91, 0x4e, 0x87, 0x90, 0x4b, 0x85, 0x8e,
-  0x49, 0x83, 0x8c, 0x46, 0x81, 0x8a, 0x44, 0x7f, 0x88, 0x41, 0x7d, 0x86,
-  0x3f, 0x7b, 0x84, 0x3d, 0x79, 0x82, 0x3b, 0x77, 0x80, 0x38, 0x75, 0x7e,
-  0x36, 0x73, 0x7d, 0x33, 0x71, 0x7b, 0x32, 0x6f, 0x7a, 0x2f, 0x6c, 0x77,
-  0x2d, 0x6b, 0x75, 0x2b, 0x69, 0x73, 0x29, 0x67, 0x71, 0x27, 0x65, 0x6f,
-  0x26, 0x64, 0x6e, 0x35, 0x6e, 0x78, 0x60, 0x8d, 0x94, 0x91, 0xb0, 0xb5,
-  0xb8, 0xcc, 0xcf, 0xd4, 0xe0, 0xe2, 0xec, 0xf1, 0xf2, 0xfd, 0xfe, 0xfe,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfa, 0xfa, 0xe4, 0xeb, 0xec,
-  0xcb, 0xd8, 0xd9, 0xab, 0xbf, 0xc3, 0x7f, 0x9f, 0xa4, 0x49, 0x75, 0x7c,
-  0x20, 0x55, 0x5d, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1d, 0x21, 0x00, 0x16, 0x19,
+  0x29, 0x47, 0x4c, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xa0, 0xc1, 0xc6, 0x69, 0x9c, 0xa4, 0x66, 0x9a, 0xa2, 0x63, 0x98, 0xa0,
+  0x61, 0x96, 0x9e, 0x5f, 0x95, 0x9d, 0x5c, 0x92, 0x9a, 0x5a, 0x90, 0x99,
+  0x57, 0x8e, 0x97, 0x55, 0x8c, 0x95, 0x53, 0x8a, 0x93, 0x50, 0x88, 0x91,
+  0x4d, 0x87, 0x8f, 0x4b, 0x84, 0x8d, 0x48, 0x82, 0x8b, 0x45, 0x7f, 0x89,
+  0x43, 0x7d, 0x87, 0x40, 0x7b, 0x84, 0x3e, 0x79, 0x82, 0x3c, 0x77, 0x80,
+  0x39, 0x75, 0x7f, 0x36, 0x73, 0x7d, 0x33, 0x70, 0x7b, 0x32, 0x6e, 0x79,
+  0x30, 0x6d, 0x77, 0x2e, 0x6b, 0x74, 0x2c, 0x69, 0x73, 0x2a, 0x67, 0x71,
+  0x27, 0x64, 0x6e, 0x26, 0x64, 0x6d, 0x31, 0x6a, 0x75, 0x52, 0x83, 0x8a,
+  0x7e, 0xa2, 0xa7, 0xa2, 0xbc, 0xc0, 0xbc, 0xce, 0xd1, 0xd0, 0xdd, 0xdf,
+  0xdf, 0xe7, 0xe9, 0xe9, 0xef, 0xf0, 0xec, 0xf1, 0xf2, 0xeb, 0xf0, 0xf1,
+  0xe6, 0xed, 0xee, 0xdb, 0xe4, 0xe5, 0xca, 0xd7, 0xd9, 0xb4, 0xc6, 0xca,
+  0x97, 0xb1, 0xb5, 0x6e, 0x91, 0x97, 0x3e, 0x6e, 0x75, 0x1d, 0x53, 0x5c,
+  0x12, 0x4a, 0x53, 0x12, 0x49, 0x52, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
+  0x10, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
+  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x01, 0x1b, 0x1f, 0x03, 0x1d, 0x21,
+  0xa6, 0xb6, 0xb9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xe4, 0xe7,
+  0x68, 0x9b, 0xa3, 0x65, 0x9a, 0xa1, 0x62, 0x98, 0xa0, 0x60, 0x96, 0x9f,
+  0x5e, 0x94, 0x9c, 0x5b, 0x92, 0x9a, 0x59, 0x90, 0x99, 0x56, 0x8e, 0x96,
+  0x55, 0x8c, 0x95, 0x52, 0x8a, 0x93, 0x50, 0x89, 0x91, 0x4d, 0x86, 0x8f,
+  0x4b, 0x85, 0x8d, 0x48, 0x82, 0x8b, 0x45, 0x80, 0x89, 0x43, 0x7e, 0x88,
+  0x40, 0x7b, 0x85, 0x3e, 0x7a, 0x83, 0x3c, 0x77, 0x80, 0x3a, 0x76, 0x7f,
+  0x37, 0x73, 0x7d, 0x34, 0x72, 0x7b, 0x33, 0x70, 0x7a, 0x30, 0x6d, 0x77,
+  0x2e, 0x6c, 0x75, 0x2c, 0x69, 0x73, 0x2a, 0x68, 0x72, 0x28, 0x66, 0x70,
+  0x26, 0x64, 0x6e, 0x25, 0x63, 0x6c, 0x23, 0x61, 0x6b, 0x22, 0x60, 0x69,
+  0x20, 0x5e, 0x67, 0x1f, 0x5c, 0x67, 0x1e, 0x5b, 0x65, 0x21, 0x5d, 0x67,
+  0x28, 0x62, 0x6a, 0x2c, 0x64, 0x6c, 0x2b, 0x63, 0x6c, 0x2a, 0x62, 0x6a,
+  0x27, 0x5f, 0x68, 0x21, 0x59, 0x62, 0x1a, 0x53, 0x5d, 0x15, 0x4f, 0x58,
+  0x15, 0x4f, 0x57, 0x13, 0x4d, 0x56, 0x13, 0x4d, 0x56, 0x12, 0x4b, 0x54,
+  0x12, 0x4a, 0x53, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
@@ -10533,20 +10469,84 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x02, 0x1c, 0x21, 0x00, 0x16, 0x1a,
-  0x78, 0x8f, 0x92, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xea, 0xf1, 0xf2,
-  0x6f, 0xa0, 0xa8, 0x5f, 0x96, 0x9e, 0x5d, 0x94, 0x9c, 0x5a, 0x91, 0x9b,
-  0x58, 0x90, 0x99, 0x56, 0x8f, 0x98, 0x54, 0x8c, 0x95, 0x52, 0x8b, 0x93,
-  0x50, 0x89, 0x92, 0x4d, 0x87, 0x90, 0x4b, 0x85, 0x8f, 0x49, 0x83, 0x8c,
-  0x46, 0x82, 0x8a, 0x43, 0x7f, 0x88, 0x41, 0x7e, 0x86, 0x3f, 0x7b, 0x85,
-  0x3d, 0x79, 0x83, 0x3b, 0x77, 0x81, 0x39, 0x75, 0x7f, 0x36, 0x73, 0x7d,
-  0x34, 0x71, 0x7c, 0x32, 0x70, 0x7a, 0x30, 0x6e, 0x78, 0x2e, 0x6c, 0x76,
-  0x2c, 0x6a, 0x74, 0x2a, 0x68, 0x72, 0x28, 0x67, 0x71, 0x26, 0x65, 0x6f,
-  0x26, 0x63, 0x6d, 0x23, 0x62, 0x6b, 0x22, 0x60, 0x6a, 0x20, 0x5f, 0x68,
-  0x1f, 0x5d, 0x67, 0x25, 0x60, 0x6b, 0x30, 0x68, 0x72, 0x3b, 0x70, 0x78,
-  0x4b, 0x7b, 0x82, 0x56, 0x83, 0x8a, 0x58, 0x84, 0x8c, 0x51, 0x7f, 0x86,
-  0x4c, 0x79, 0x81, 0x3f, 0x70, 0x77, 0x31, 0x65, 0x6d, 0x26, 0x5b, 0x64,
-  0x18, 0x51, 0x5a, 0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x12, 0x4b, 0x54,
+  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x00, 0x17, 0x1a, 0x3d, 0x5b, 0x5f,
+  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfb, 0xfb, 0x86, 0xaf, 0xb6,
+  0x63, 0x98, 0xa1, 0x61, 0x97, 0x9f, 0x5f, 0x95, 0x9d, 0x5d, 0x93, 0x9c,
+  0x5a, 0x91, 0x9a, 0x58, 0x90, 0x99, 0x55, 0x8e, 0x96, 0x54, 0x8c, 0x95,
+  0x51, 0x8a, 0x93, 0x4f, 0x88, 0x91, 0x4d, 0x87, 0x90, 0x4a, 0x84, 0x8d,
+  0x48, 0x83, 0x8b, 0x45, 0x80, 0x8a, 0x43, 0x7f, 0x88, 0x40, 0x7c, 0x86,
+  0x3e, 0x7a, 0x84, 0x3c, 0x78, 0x81, 0x3a, 0x76, 0x7f, 0x37, 0x74, 0x7d,
+  0x35, 0x72, 0x7c, 0x33, 0x71, 0x7a, 0x31, 0x6e, 0x79, 0x2f, 0x6c, 0x77,
+  0x2d, 0x6b, 0x75, 0x2b, 0x69, 0x73, 0x29, 0x67, 0x71, 0x27, 0x65, 0x6f,
+  0x26, 0x63, 0x6d, 0x24, 0x62, 0x6c, 0x22, 0x60, 0x6a, 0x21, 0x5f, 0x69,
+  0x1f, 0x5d, 0x67, 0x1e, 0x5b, 0x66, 0x1d, 0x5a, 0x64, 0x1c, 0x59, 0x63,
+  0x1a, 0x57, 0x60, 0x19, 0x56, 0x60, 0x17, 0x55, 0x5e, 0x17, 0x54, 0x5d,
+  0x17, 0x52, 0x5c, 0x16, 0x51, 0x5a, 0x16, 0x50, 0x5a, 0x15, 0x4f, 0x58,
+  0x14, 0x4e, 0x57, 0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x12, 0x4b, 0x54,
+  0x12, 0x4a, 0x53, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
+  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
+  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
+  0x02, 0x20, 0x24, 0x00, 0x1b, 0x1f, 0x0b, 0x28, 0x2c, 0xca, 0xd5, 0xd6,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb1, 0xcc, 0xd1, 0x61, 0x98, 0xa0,
+  0x5f, 0x96, 0x9f, 0x5d, 0x95, 0x9d, 0x5b, 0x93, 0x9b, 0x59, 0x91, 0x9a,
+  0x57, 0x90, 0x98, 0x55, 0x8e, 0x97, 0x53, 0x8c, 0x95, 0x51, 0x8a, 0x93,
+  0x4e, 0x88, 0x91, 0x4c, 0x86, 0x8f, 0x4a, 0x85, 0x8e, 0x48, 0x82, 0x8c,
+  0x45, 0x81, 0x8a, 0x42, 0x7e, 0x88, 0x40, 0x7d, 0x86, 0x3e, 0x7a, 0x84,
+  0x3c, 0x78, 0x82, 0x3a, 0x77, 0x80, 0x38, 0x75, 0x7e, 0x35, 0x73, 0x7c,
+  0x33, 0x71, 0x7b, 0x31, 0x6f, 0x79, 0x2f, 0x6d, 0x78, 0x2d, 0x6b, 0x76,
+  0x2b, 0x6a, 0x74, 0x29, 0x67, 0x71, 0x27, 0x66, 0x70, 0x26, 0x65, 0x6f,
+  0x25, 0x62, 0x6c, 0x22, 0x61, 0x6a, 0x21, 0x5f, 0x6a, 0x20, 0x5f, 0x68,
+  0x1f, 0x5d, 0x67, 0x1d, 0x5b, 0x65, 0x1c, 0x59, 0x64, 0x1b, 0x59, 0x62,
+  0x1a, 0x57, 0x60, 0x19, 0x56, 0x60, 0x17, 0x55, 0x5e, 0x17, 0x53, 0x5d,
+  0x17, 0x52, 0x5c, 0x16, 0x51, 0x5a, 0x15, 0x50, 0x59, 0x15, 0x4f, 0x58,
+  0x14, 0x4e, 0x57, 0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x12, 0x4b, 0x54,
   0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x11, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
@@ -10597,19 +10597,19 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x02, 0x1e, 0x23, 0x00, 0x17, 0x1b, 0x1f, 0x3d, 0x41,
-  0xfa, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xbd, 0xc2,
-  0x5d, 0x95, 0x9e, 0x5c, 0x94, 0x9c, 0x59, 0x92, 0x9a, 0x57, 0x90, 0x99,
-  0x55, 0x8e, 0x97, 0x53, 0x8d, 0x95, 0x51, 0x8b, 0x94, 0x4f, 0x89, 0x92,
-  0x4c, 0x87, 0x90, 0x4a, 0x85, 0x8e, 0x49, 0x84, 0x8d, 0x46, 0x81, 0x8a,
-  0x43, 0x80, 0x88, 0x41, 0x7e, 0x87, 0x3e, 0x7c, 0x85, 0x3d, 0x7a, 0x83,
-  0x3b, 0x77, 0x81, 0x39, 0x76, 0x7f, 0x36, 0x73, 0x7d, 0x34, 0x72, 0x7c,
-  0x32, 0x70, 0x7a, 0x30, 0x6f, 0x78, 0x2e, 0x6d, 0x77, 0x2c, 0x6a, 0x75,
-  0x2a, 0x69, 0x73, 0x28, 0x67, 0x71, 0x26, 0x65, 0x70, 0x26, 0x64, 0x6e,
-  0x24, 0x62, 0x6c, 0x22, 0x61, 0x6a, 0x20, 0x5f, 0x69, 0x1f, 0x5e, 0x67,
-  0x1e, 0x5c, 0x66, 0x1d, 0x5b, 0x65, 0x1c, 0x59, 0x64, 0x1a, 0x58, 0x61,
-  0x19, 0x56, 0x60, 0x18, 0x55, 0x5f, 0x17, 0x55, 0x5e, 0x17, 0x53, 0x5d,
-  0x16, 0x51, 0x5b, 0x16, 0x51, 0x5a, 0x15, 0x50, 0x59, 0x15, 0x4f, 0x58,
+  0x02, 0x1f, 0x24, 0x00, 0x19, 0x1d, 0x6a, 0x83, 0x87, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xdd, 0xe9, 0xeb, 0x64, 0x9a, 0xa2, 0x5d, 0x95, 0x9e,
+  0x5c, 0x94, 0x9d, 0x5a, 0x92, 0x9b, 0x57, 0x90, 0x99, 0x55, 0x8e, 0x98,
+  0x55, 0x8e, 0x97, 0x52, 0x8c, 0x95, 0x4f, 0x89, 0x92, 0x4d, 0x87, 0x90,
+  0x4b, 0x86, 0x8f, 0x49, 0x84, 0x8d, 0x48, 0x83, 0x8c, 0x45, 0x80, 0x8a,
+  0x42, 0x7f, 0x88, 0x3f, 0x7c, 0x86, 0x3e, 0x7b, 0x84, 0x3c, 0x79, 0x83,
+  0x3a, 0x77, 0x81, 0x37, 0x75, 0x7e, 0x35, 0x73, 0x7c, 0x33, 0x72, 0x7b,
+  0x32, 0x6f, 0x7a, 0x2f, 0x6e, 0x78, 0x2d, 0x6c, 0x77, 0x2b, 0x6a, 0x74,
+  0x29, 0x68, 0x72, 0x28, 0x67, 0x71, 0x26, 0x65, 0x70, 0x25, 0x63, 0x6d,
+  0x24, 0x62, 0x6c, 0x21, 0x60, 0x6a, 0x20, 0x5f, 0x69, 0x1f, 0x5e, 0x67,
+  0x1e, 0x5c, 0x66, 0x1c, 0x5a, 0x65, 0x1b, 0x59, 0x63, 0x1a, 0x58, 0x61,
+  0x19, 0x56, 0x60, 0x19, 0x56, 0x60, 0x17, 0x54, 0x5e, 0x17, 0x53, 0x5d,
+  0x16, 0x51, 0x5b, 0x16, 0x51, 0x5a, 0x15, 0x50, 0x59, 0x14, 0x4e, 0x58,
   0x14, 0x4e, 0x57, 0x12, 0x4c, 0x55, 0x12, 0x4c, 0x55, 0x12, 0x4b, 0x54,
   0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
@@ -10661,18 +10661,18 @@
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
   0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x01, 0x1d, 0x21, 0x02, 0x1c, 0x21, 0x98, 0xab, 0xae,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xdf, 0xe2, 0x5d, 0x95, 0x9d,
-  0x5b, 0x93, 0x9c, 0x59, 0x92, 0x9a, 0x56, 0x90, 0x98, 0x55, 0x8e, 0x97,
-  0x52, 0x8c, 0x95, 0x50, 0x8b, 0x94, 0x4e, 0x89, 0x92, 0x4c, 0x87, 0x90,
-  0x49, 0x85, 0x8e, 0x48, 0x83, 0x8c, 0x46, 0x82, 0x8b, 0x43, 0x7f, 0x89,
-  0x40, 0x7e, 0x87, 0x3e, 0x7c, 0x85, 0x3d, 0x7a, 0x83, 0x3a, 0x78, 0x82,
-  0x38, 0x76, 0x80, 0x36, 0x74, 0x7e, 0x34, 0x72, 0x7c, 0x32, 0x71, 0x7a,
-  0x31, 0x6f, 0x79, 0x2e, 0x6d, 0x77, 0x2c, 0x6b, 0x76, 0x2a, 0x69, 0x74,
-  0x29, 0x68, 0x72, 0x27, 0x66, 0x70, 0x26, 0x65, 0x6f, 0x25, 0x63, 0x6d,
-  0x23, 0x61, 0x6b, 0x21, 0x60, 0x6a, 0x1f, 0x5e, 0x68, 0x1e, 0x5d, 0x67,
-  0x1d, 0x5c, 0x65, 0x1c, 0x5a, 0x65, 0x1b, 0x59, 0x63, 0x1a, 0x58, 0x61,
-  0x19, 0x56, 0x60, 0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x17, 0x53, 0x5d,
+  0x00, 0x1a, 0x1e, 0x22, 0x42, 0x47, 0xf9, 0xfb, 0xfb, 0xff, 0xff, 0xff,
+  0xf7, 0xfa, 0xfa, 0x81, 0xad, 0xb4, 0x5c, 0x94, 0x9d, 0x5b, 0x94, 0x9c,
+  0x59, 0x92, 0x9b, 0x57, 0x90, 0x99, 0x55, 0x8f, 0x97, 0x52, 0x8c, 0x96,
+  0x50, 0x8b, 0x94, 0x4f, 0x8a, 0x93, 0x4c, 0x88, 0x91, 0x4a, 0x86, 0x8f,
+  0x49, 0x84, 0x8e, 0x47, 0x82, 0x8c, 0x44, 0x80, 0x8a, 0x42, 0x7e, 0x88,
+  0x3f, 0x7d, 0x86, 0x3e, 0x7b, 0x85, 0x3b, 0x79, 0x82, 0x39, 0x77, 0x81,
+  0x37, 0x75, 0x7f, 0x35, 0x74, 0x7d, 0x33, 0x72, 0x7b, 0x32, 0x70, 0x7a,
+  0x30, 0x6e, 0x79, 0x2d, 0x6d, 0x77, 0x2b, 0x6b, 0x75, 0x2a, 0x69, 0x74,
+  0x28, 0x68, 0x72, 0x26, 0x65, 0x70, 0x26, 0x65, 0x6f, 0x24, 0x63, 0x6d,
+  0x23, 0x61, 0x6b, 0x20, 0x60, 0x69, 0x1f, 0x5e, 0x68, 0x1e, 0x5d, 0x67,
+  0x1d, 0x5c, 0x65, 0x1c, 0x5a, 0x65, 0x1a, 0x58, 0x62, 0x19, 0x57, 0x61,
+  0x18, 0x55, 0x5f, 0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x52, 0x5c,
   0x16, 0x51, 0x5b, 0x15, 0x50, 0x59, 0x15, 0x50, 0x59, 0x14, 0x4e, 0x58,
   0x14, 0x4e, 0x57, 0x12, 0x4c, 0x55, 0x12, 0x4c, 0x55, 0x11, 0x4a, 0x53,
   0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x11, 0x47, 0x50, 0x10, 0x47, 0x4f,
@@ -10724,20 +10724,20 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x02, 0x20, 0x24, 0x00, 0x18, 0x1c, 0x3b, 0x58, 0x5e, 0xfe, 0xfe, 0xfe,
-  0xff, 0xff, 0xff, 0xf2, 0xf6, 0xf7, 0x74, 0xa4, 0xac, 0x58, 0x92, 0x9a,
-  0x57, 0x90, 0x9a, 0x55, 0x8f, 0x98, 0x53, 0x8d, 0x96, 0x50, 0x8b, 0x94,
-  0x4e, 0x8a, 0x93, 0x4d, 0x89, 0x92, 0x4a, 0x86, 0x90, 0x49, 0x84, 0x8e,
-  0x47, 0x83, 0x8c, 0x45, 0x81, 0x8b, 0x43, 0x80, 0x89, 0x41, 0x7e, 0x87,
-  0x3e, 0x7c, 0x85, 0x3c, 0x7a, 0x84, 0x3a, 0x79, 0x82, 0x38, 0x76, 0x81,
-  0x36, 0x74, 0x7f, 0x34, 0x73, 0x7c, 0x32, 0x71, 0x7a, 0x31, 0x70, 0x79,
-  0x2f, 0x6d, 0x78, 0x2c, 0x6c, 0x76, 0x2b, 0x6b, 0x75, 0x29, 0x68, 0x73,
-  0x27, 0x67, 0x71, 0x26, 0x65, 0x6f, 0x25, 0x64, 0x6e, 0x24, 0x63, 0x6d,
-  0x22, 0x60, 0x6b, 0x20, 0x60, 0x69, 0x1e, 0x5d, 0x68, 0x1d, 0x5d, 0x66,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x00, 0x1f, 0x24,
+  0x05, 0x24, 0x29, 0xae, 0xbe, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xa4, 0xc4, 0xc9, 0x5a, 0x93, 0x9c, 0x58, 0x92, 0x9b, 0x57, 0x91, 0x9a,
+  0x55, 0x8f, 0x99, 0x52, 0x8d, 0x96, 0x50, 0x8c, 0x94, 0x4f, 0x8a, 0x94,
+  0x4d, 0x89, 0x92, 0x4b, 0x88, 0x91, 0x49, 0x86, 0x8f, 0x48, 0x84, 0x8d,
+  0x46, 0x82, 0x8c, 0x43, 0x80, 0x89, 0x41, 0x7f, 0x88, 0x3f, 0x7c, 0x86,
+  0x3d, 0x7b, 0x84, 0x3b, 0x79, 0x83, 0x39, 0x78, 0x81, 0x37, 0x76, 0x80,
+  0x35, 0x74, 0x7e, 0x33, 0x72, 0x7c, 0x32, 0x70, 0x7a, 0x30, 0x6f, 0x79,
+  0x2e, 0x6d, 0x77, 0x2c, 0x6c, 0x76, 0x2a, 0x6a, 0x75, 0x28, 0x68, 0x73,
+  0x26, 0x66, 0x70, 0x26, 0x65, 0x6f, 0x24, 0x64, 0x6e, 0x23, 0x62, 0x6c,
+  0x22, 0x60, 0x6b, 0x1f, 0x5f, 0x68, 0x1e, 0x5d, 0x68, 0x1d, 0x5d, 0x66,
   0x1c, 0x5b, 0x65, 0x1b, 0x59, 0x64, 0x1a, 0x58, 0x62, 0x19, 0x57, 0x61,
-  0x19, 0x56, 0x60, 0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x52, 0x5c,
-  0x16, 0x51, 0x5b, 0x15, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x14, 0x4e, 0x58,
+  0x18, 0x55, 0x5f, 0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x52, 0x5c,
+  0x15, 0x50, 0x5a, 0x15, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x14, 0x4e, 0x58,
   0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x12, 0x4c, 0x55, 0x11, 0x4a, 0x53,
   0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
@@ -10788,86 +10788,22 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x21, 0x26,
-  0x00, 0x1c, 0x20, 0x0d, 0x2b, 0x30, 0xcd, 0xd7, 0xd8, 0xff, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0x9b, 0xbd, 0xc3, 0x56, 0x91, 0x9a, 0x55, 0x90, 0x99,
-  0x53, 0x8e, 0x98, 0x52, 0x8d, 0x96, 0x4f, 0x8b, 0x94, 0x4d, 0x89, 0x93,
-  0x4b, 0x88, 0x91, 0x49, 0x86, 0x90, 0x48, 0x84, 0x8e, 0x46, 0x82, 0x8c,
-  0x44, 0x81, 0x8b, 0x42, 0x7f, 0x89, 0x40, 0x7e, 0x88, 0x3e, 0x7c, 0x86,
-  0x3c, 0x7b, 0x84, 0x3a, 0x79, 0x83, 0x38, 0x77, 0x81, 0x36, 0x75, 0x7f,
-  0x34, 0x73, 0x7d, 0x32, 0x72, 0x7b, 0x31, 0x70, 0x79, 0x2f, 0x6e, 0x78,
-  0x2d, 0x6c, 0x77, 0x2b, 0x6b, 0x75, 0x29, 0x69, 0x74, 0x27, 0x67, 0x72,
-  0x26, 0x66, 0x70, 0x25, 0x64, 0x6e, 0x24, 0x64, 0x6e, 0x22, 0x61, 0x6c,
-  0x21, 0x60, 0x6a, 0x1f, 0x5f, 0x68, 0x1e, 0x5d, 0x68, 0x1c, 0x5c, 0x66,
-  0x1b, 0x5a, 0x64, 0x1a, 0x59, 0x63, 0x19, 0x57, 0x62, 0x18, 0x56, 0x60,
-  0x18, 0x55, 0x5f, 0x18, 0x55, 0x5f, 0x16, 0x53, 0x5d, 0x15, 0x51, 0x5b,
-  0x15, 0x50, 0x5a, 0x15, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x14, 0x4e, 0x58,
-  0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
-  0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
-  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
-  0x0f, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x02, 0x20, 0x25,
-  0x00, 0x1b, 0x1f, 0x77, 0x90, 0x93, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-  0xc5, 0xd9, 0xdc, 0x53, 0x8f, 0x98, 0x52, 0x8e, 0x98, 0x52, 0x8e, 0x96,
-  0x50, 0x8c, 0x95, 0x4e, 0x8a, 0x94, 0x4b, 0x88, 0x92, 0x4a, 0x87, 0x91,
-  0x49, 0x86, 0x8f, 0x47, 0x85, 0x8e, 0x45, 0x83, 0x8c, 0x43, 0x81, 0x8a,
-  0x41, 0x7f, 0x89, 0x3f, 0x7d, 0x87, 0x3d, 0x7c, 0x86, 0x3c, 0x7a, 0x84,
-  0x39, 0x79, 0x82, 0x37, 0x77, 0x81, 0x35, 0x75, 0x7f, 0x33, 0x73, 0x7e,
-  0x32, 0x72, 0x7c, 0x31, 0x70, 0x7a, 0x2f, 0x6e, 0x78, 0x2d, 0x6d, 0x77,
-  0x2c, 0x6b, 0x76, 0x29, 0x6a, 0x74, 0x27, 0x68, 0x73, 0x26, 0x66, 0x71,
-  0x25, 0x65, 0x6f, 0x24, 0x64, 0x6e, 0x23, 0x63, 0x6d, 0x21, 0x61, 0x6b,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x22, 0x27, 0x00, 0x1b, 0x20,
+  0x5e, 0x7a, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xdb, 0xde,
+  0x57, 0x92, 0x9b, 0x55, 0x90, 0x99, 0x54, 0x8f, 0x99, 0x53, 0x8f, 0x98,
+  0x52, 0x8d, 0x96, 0x50, 0x8c, 0x95, 0x4d, 0x8a, 0x93, 0x4c, 0x88, 0x92,
+  0x4a, 0x87, 0x90, 0x49, 0x86, 0x8f, 0x47, 0x84, 0x8d, 0x45, 0x82, 0x8b,
+  0x42, 0x80, 0x8a, 0x40, 0x7e, 0x88, 0x3e, 0x7d, 0x87, 0x3d, 0x7b, 0x85,
+  0x3b, 0x7a, 0x83, 0x39, 0x78, 0x82, 0x37, 0x77, 0x80, 0x35, 0x75, 0x7f,
+  0x33, 0x72, 0x7d, 0x32, 0x71, 0x7b, 0x30, 0x6f, 0x79, 0x2e, 0x6e, 0x77,
+  0x2d, 0x6c, 0x77, 0x2a, 0x6b, 0x75, 0x28, 0x69, 0x73, 0x27, 0x67, 0x72,
+  0x26, 0x66, 0x70, 0x25, 0x64, 0x6e, 0x23, 0x63, 0x6d, 0x22, 0x61, 0x6c,
   0x20, 0x5f, 0x69, 0x1e, 0x5e, 0x68, 0x1d, 0x5d, 0x67, 0x1c, 0x5c, 0x66,
-  0x1a, 0x5a, 0x63, 0x1a, 0x59, 0x63, 0x19, 0x57, 0x62, 0x18, 0x56, 0x60,
-  0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x15, 0x51, 0x5b,
+  0x1b, 0x5a, 0x64, 0x1a, 0x59, 0x63, 0x19, 0x57, 0x62, 0x19, 0x57, 0x61,
+  0x18, 0x55, 0x5f, 0x18, 0x55, 0x5f, 0x16, 0x53, 0x5d, 0x16, 0x52, 0x5c,
   0x15, 0x50, 0x5a, 0x14, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x13, 0x4d, 0x57,
   0x13, 0x4d, 0x56, 0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
-  0x11, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
+  0x11, 0x49, 0x52, 0x11, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0f, 0x44, 0x4c,
   0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
@@ -10916,20 +10852,20 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x02, 0x23, 0x27, 0x00, 0x1b, 0x1f,
-  0x31, 0x51, 0x56, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xe5, 0xee, 0xef,
-  0x64, 0x9a, 0xa2, 0x50, 0x8c, 0x96, 0x4f, 0x8c, 0x96, 0x4e, 0x8b, 0x94,
-  0x4c, 0x89, 0x93, 0x4b, 0x89, 0x92, 0x49, 0x87, 0x90, 0x47, 0x85, 0x8f,
-  0x45, 0x83, 0x8d, 0x43, 0x82, 0x8c, 0x41, 0x80, 0x8a, 0x40, 0x7f, 0x88,
-  0x3e, 0x7e, 0x87, 0x3d, 0x7b, 0x85, 0x3b, 0x7a, 0x84, 0x39, 0x78, 0x82,
-  0x36, 0x77, 0x80, 0x35, 0x75, 0x80, 0x33, 0x74, 0x7e, 0x32, 0x72, 0x7c,
-  0x31, 0x70, 0x7b, 0x2f, 0x6f, 0x79, 0x2d, 0x6d, 0x77, 0x2b, 0x6c, 0x76,
-  0x2a, 0x6a, 0x75, 0x27, 0x69, 0x73, 0x26, 0x67, 0x72, 0x25, 0x65, 0x70,
-  0x24, 0x64, 0x6f, 0x23, 0x63, 0x6d, 0x21, 0x62, 0x6c, 0x20, 0x60, 0x6a,
+  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x00, 0x1c, 0x21, 0x27, 0x48, 0x4e,
+  0xf9, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xe2, 0xec, 0xee, 0x64, 0x9a, 0xa4,
+  0x53, 0x90, 0x98, 0x52, 0x8e, 0x97, 0x51, 0x8d, 0x97, 0x50, 0x8c, 0x95,
+  0x4e, 0x8a, 0x94, 0x4c, 0x89, 0x92, 0x4a, 0x88, 0x91, 0x49, 0x86, 0x90,
+  0x47, 0x85, 0x8e, 0x45, 0x83, 0x8d, 0x43, 0x81, 0x8b, 0x41, 0x7f, 0x89,
+  0x3f, 0x7e, 0x88, 0x3d, 0x7c, 0x86, 0x3d, 0x7b, 0x85, 0x3b, 0x79, 0x83,
+  0x38, 0x78, 0x81, 0x36, 0x76, 0x80, 0x34, 0x75, 0x7e, 0x32, 0x73, 0x7d,
+  0x32, 0x71, 0x7c, 0x30, 0x70, 0x79, 0x2e, 0x6e, 0x77, 0x2c, 0x6c, 0x76,
+  0x2b, 0x6b, 0x76, 0x28, 0x6a, 0x73, 0x27, 0x68, 0x73, 0x26, 0x66, 0x71,
+  0x25, 0x65, 0x6f, 0x23, 0x63, 0x6d, 0x22, 0x62, 0x6c, 0x21, 0x61, 0x6b,
   0x1f, 0x5e, 0x69, 0x1d, 0x5e, 0x67, 0x1c, 0x5c, 0x67, 0x1b, 0x5b, 0x65,
   0x1a, 0x5a, 0x63, 0x19, 0x58, 0x63, 0x18, 0x56, 0x61, 0x18, 0x56, 0x60,
   0x18, 0x55, 0x5f, 0x17, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x15, 0x51, 0x5b,
-  0x14, 0x50, 0x5a, 0x14, 0x50, 0x59, 0x13, 0x4e, 0x58, 0x13, 0x4d, 0x57,
+  0x15, 0x50, 0x5a, 0x14, 0x50, 0x59, 0x14, 0x4f, 0x59, 0x13, 0x4d, 0x57,
   0x13, 0x4d, 0x56, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
   0x11, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0e, 0x43, 0x4b,
@@ -10980,21 +10916,21 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x03, 0x24, 0x29, 0x00, 0x1e, 0x23, 0x0e, 0x2e, 0x33,
-  0xca, 0xd6, 0xd7, 0xff, 0xff, 0xff, 0xf9, 0xfb, 0xfb, 0x7a, 0xa9, 0xb0,
-  0x4e, 0x8c, 0x95, 0x4c, 0x8a, 0x94, 0x4b, 0x89, 0x93, 0x4a, 0x89, 0x92,
-  0x48, 0x87, 0x91, 0x47, 0x86, 0x90, 0x45, 0x84, 0x8e, 0x43, 0x82, 0x8d,
-  0x42, 0x82, 0x8b, 0x41, 0x81, 0x8b, 0x3e, 0x7e, 0x88, 0x3d, 0x7d, 0x87,
-  0x3c, 0x7c, 0x86, 0x3a, 0x7a, 0x84, 0x39, 0x79, 0x83, 0x37, 0x77, 0x81,
-  0x34, 0x76, 0x7f, 0x32, 0x73, 0x7e, 0x32, 0x73, 0x7c, 0x30, 0x71, 0x7b,
-  0x2e, 0x6f, 0x79, 0x2d, 0x6e, 0x78, 0x2b, 0x6c, 0x76, 0x2a, 0x6b, 0x75,
-  0x28, 0x69, 0x74, 0x26, 0x68, 0x72, 0x25, 0x66, 0x71, 0x24, 0x64, 0x70,
-  0x23, 0x64, 0x6e, 0x21, 0x62, 0x6c, 0x20, 0x61, 0x6b, 0x1f, 0x5f, 0x6a,
+  0x03, 0x25, 0x2b, 0x00, 0x20, 0x25, 0x0d, 0x2d, 0x33, 0xc3, 0xd0, 0xd2,
+  0xff, 0xff, 0xff, 0xf3, 0xf8, 0xf8, 0x76, 0xa5, 0xad, 0x51, 0x8e, 0x97,
+  0x50, 0x8d, 0x96, 0x4e, 0x8b, 0x95, 0x4d, 0x8b, 0x94, 0x4c, 0x8a, 0x93,
+  0x4a, 0x88, 0x92, 0x49, 0x87, 0x91, 0x47, 0x85, 0x8f, 0x45, 0x83, 0x8e,
+  0x44, 0x83, 0x8c, 0x42, 0x82, 0x8b, 0x40, 0x80, 0x89, 0x3f, 0x7e, 0x88,
+  0x3d, 0x7c, 0x86, 0x3c, 0x7b, 0x85, 0x3a, 0x7a, 0x84, 0x38, 0x77, 0x82,
+  0x35, 0x76, 0x80, 0x34, 0x75, 0x7f, 0x32, 0x73, 0x7d, 0x31, 0x71, 0x7c,
+  0x30, 0x70, 0x7a, 0x2e, 0x6f, 0x78, 0x2c, 0x6c, 0x76, 0x2b, 0x6c, 0x76,
+  0x29, 0x6a, 0x74, 0x27, 0x69, 0x73, 0x26, 0x67, 0x72, 0x25, 0x65, 0x70,
+  0x23, 0x64, 0x6e, 0x22, 0x62, 0x6c, 0x21, 0x62, 0x6c, 0x20, 0x60, 0x6a,
   0x1e, 0x5e, 0x68, 0x1c, 0x5d, 0x67, 0x1b, 0x5b, 0x66, 0x1a, 0x5b, 0x64,
-  0x19, 0x59, 0x63, 0x19, 0x58, 0x63, 0x18, 0x56, 0x60, 0x18, 0x56, 0x60,
-  0x17, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x15, 0x52, 0x5c, 0x15, 0x51, 0x5b,
+  0x19, 0x59, 0x63, 0x19, 0x58, 0x63, 0x18, 0x56, 0x61, 0x18, 0x56, 0x60,
+  0x17, 0x54, 0x5e, 0x17, 0x54, 0x5e, 0x15, 0x52, 0x5c, 0x15, 0x51, 0x5b,
   0x14, 0x50, 0x5a, 0x14, 0x50, 0x59, 0x13, 0x4e, 0x58, 0x13, 0x4d, 0x57,
-  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
+  0x13, 0x4d, 0x56, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0e, 0x43, 0x4b,
   0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
@@ -11044,21 +10980,21 @@
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
   0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x03, 0x25, 0x2a, 0x01, 0x23, 0x28, 0x00, 0x20, 0x25, 0x89, 0xa0, 0xa4,
-  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xbc, 0xc2, 0x4b, 0x8a, 0x94,
-  0x4a, 0x8a, 0x93, 0x48, 0x88, 0x92, 0x47, 0x87, 0x91, 0x47, 0x86, 0x90,
-  0x45, 0x84, 0x8f, 0x44, 0x84, 0x8d, 0x42, 0x82, 0x8c, 0x41, 0x81, 0x8b,
-  0x3f, 0x80, 0x8a, 0x3d, 0x7f, 0x88, 0x3d, 0x7d, 0x87, 0x3b, 0x7b, 0x85,
-  0x39, 0x7a, 0x84, 0x38, 0x78, 0x82, 0x36, 0x77, 0x81, 0x34, 0x75, 0x7f,
-  0x32, 0x74, 0x7e, 0x31, 0x72, 0x7d, 0x30, 0x72, 0x7b, 0x2e, 0x6f, 0x7a,
-  0x2c, 0x6d, 0x78, 0x2b, 0x6d, 0x76, 0x29, 0x6a, 0x74, 0x28, 0x6a, 0x74,
-  0x27, 0x68, 0x73, 0x25, 0x67, 0x71, 0x24, 0x65, 0x70, 0x23, 0x64, 0x6f,
-  0x21, 0x62, 0x6d, 0x20, 0x61, 0x6b, 0x1f, 0x60, 0x6b, 0x1e, 0x5f, 0x69,
-  0x1d, 0x5d, 0x67, 0x1b, 0x5c, 0x66, 0x1a, 0x5b, 0x65, 0x19, 0x5a, 0x64,
-  0x18, 0x58, 0x62, 0x18, 0x57, 0x62, 0x18, 0x56, 0x60, 0x17, 0x55, 0x5f,
-  0x17, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
+  0x01, 0x24, 0x29, 0x01, 0x22, 0x27, 0x89, 0x9f, 0xa3, 0xff, 0xff, 0xff,
+  0xfe, 0xff, 0xff, 0x8b, 0xb4, 0xba, 0x4e, 0x8c, 0x96, 0x4d, 0x8b, 0x95,
+  0x4c, 0x8b, 0x94, 0x4b, 0x89, 0x93, 0x49, 0x88, 0x92, 0x48, 0x88, 0x91,
+  0x47, 0x86, 0x90, 0x46, 0x85, 0x8f, 0x44, 0x84, 0x8d, 0x42, 0x82, 0x8c,
+  0x40, 0x80, 0x8a, 0x3f, 0x80, 0x8a, 0x3d, 0x7e, 0x88, 0x3c, 0x7c, 0x86,
+  0x3b, 0x7b, 0x85, 0x39, 0x79, 0x83, 0x37, 0x78, 0x82, 0x36, 0x76, 0x80,
+  0x33, 0x75, 0x7e, 0x32, 0x73, 0x7d, 0x31, 0x72, 0x7c, 0x2f, 0x70, 0x7b,
+  0x2e, 0x6f, 0x79, 0x2c, 0x6d, 0x77, 0x2a, 0x6b, 0x75, 0x29, 0x6a, 0x74,
+  0x27, 0x68, 0x73, 0x26, 0x68, 0x72, 0x25, 0x66, 0x71, 0x23, 0x64, 0x6f,
+  0x22, 0x63, 0x6d, 0x21, 0x62, 0x6c, 0x20, 0x61, 0x6b, 0x1f, 0x5f, 0x6a,
+  0x1e, 0x5e, 0x68, 0x1b, 0x5c, 0x66, 0x1a, 0x5b, 0x65, 0x1a, 0x5b, 0x64,
+  0x19, 0x59, 0x63, 0x18, 0x57, 0x62, 0x18, 0x56, 0x61, 0x17, 0x55, 0x5f,
+  0x17, 0x54, 0x5e, 0x17, 0x54, 0x5e, 0x15, 0x52, 0x5c, 0x14, 0x51, 0x5b,
   0x14, 0x50, 0x5a, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58, 0x13, 0x4d, 0x57,
-  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x10, 0x4a, 0x53,
+  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
   0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
   0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
@@ -11107,31 +11043,31 @@
   0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x02, 0x25, 0x2a, 0x00, 0x1d, 0x22, 0x4d, 0x6c, 0x71, 0xfe, 0xff, 0xff,
-  0xff, 0xff, 0xff, 0xb1, 0xcd, 0xd1, 0x48, 0x88, 0x93, 0x47, 0x88, 0x92,
-  0x47, 0x87, 0x91, 0x46, 0x86, 0x90, 0x45, 0x85, 0x90, 0x43, 0x84, 0x8e,
-  0x42, 0x83, 0x8d, 0x41, 0x82, 0x8c, 0x3e, 0x80, 0x8a, 0x3d, 0x7f, 0x89,
-  0x3d, 0x7e, 0x88, 0x3b, 0x7d, 0x87, 0x3a, 0x7b, 0x85, 0x38, 0x79, 0x83,
-  0x37, 0x79, 0x83, 0x35, 0x76, 0x81, 0x34, 0x76, 0x80, 0x32, 0x74, 0x7e,
-  0x30, 0x72, 0x7c, 0x2f, 0x71, 0x7c, 0x2d, 0x70, 0x79, 0x2c, 0x6e, 0x79,
-  0x2a, 0x6c, 0x77, 0x29, 0x6b, 0x75, 0x28, 0x6a, 0x74, 0x26, 0x69, 0x73,
-  0x26, 0x67, 0x72, 0x24, 0x66, 0x70, 0x23, 0x65, 0x70, 0x21, 0x62, 0x6e,
-  0x20, 0x62, 0x6c, 0x1f, 0x60, 0x6b, 0x1e, 0x60, 0x6a, 0x1d, 0x5e, 0x68,
-  0x1c, 0x5c, 0x67, 0x1a, 0x5c, 0x65, 0x19, 0x5a, 0x65, 0x18, 0x59, 0x63,
-  0x18, 0x58, 0x62, 0x18, 0x57, 0x61, 0x17, 0x55, 0x60, 0x17, 0x55, 0x5f,
-  0x16, 0x53, 0x5d, 0x16, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
-  0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58, 0x12, 0x4c, 0x56,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x02, 0x26, 0x2c,
+  0x00, 0x1f, 0x24, 0x56, 0x73, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0x9d, 0xc0, 0xc6, 0x4b, 0x8b, 0x95, 0x4a, 0x8a, 0x94, 0x49, 0x89, 0x93,
+  0x48, 0x88, 0x92, 0x47, 0x87, 0x91, 0x47, 0x86, 0x91, 0x45, 0x85, 0x8f,
+  0x44, 0x84, 0x8e, 0x43, 0x83, 0x8d, 0x41, 0x82, 0x8b, 0x3f, 0x80, 0x8a,
+  0x3e, 0x7f, 0x89, 0x3d, 0x7e, 0x88, 0x3b, 0x7c, 0x86, 0x3a, 0x7a, 0x84,
+  0x38, 0x79, 0x83, 0x37, 0x78, 0x82, 0x35, 0x76, 0x81, 0x33, 0x74, 0x7f,
+  0x32, 0x74, 0x7d, 0x30, 0x72, 0x7c, 0x2f, 0x71, 0x7b, 0x2d, 0x6f, 0x79,
+  0x2c, 0x6d, 0x78, 0x2a, 0x6c, 0x76, 0x29, 0x6a, 0x74, 0x27, 0x69, 0x73,
+  0x26, 0x68, 0x73, 0x25, 0x67, 0x71, 0x23, 0x65, 0x70, 0x22, 0x63, 0x6e,
+  0x21, 0x62, 0x6d, 0x20, 0x61, 0x6b, 0x1f, 0x60, 0x6b, 0x1e, 0x5f, 0x69,
+  0x1d, 0x5d, 0x67, 0x1b, 0x5c, 0x66, 0x1a, 0x5b, 0x65, 0x19, 0x5a, 0x64,
+  0x18, 0x58, 0x62, 0x18, 0x57, 0x61, 0x18, 0x56, 0x60, 0x17, 0x55, 0x5f,
+  0x16, 0x53, 0x5d, 0x16, 0x53, 0x5d, 0x15, 0x52, 0x5c, 0x14, 0x51, 0x5b,
+  0x14, 0x50, 0x5a, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58, 0x12, 0x4c, 0x56,
   0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x10, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
-  0x0f, 0x46, 0x4f, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
+  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
   0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
   0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
   0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x45, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11141,7 +11077,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x07, 0x5e, 0x6a, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
@@ -11171,20 +11107,84 @@
   0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x03, 0x27, 0x2c,
-  0x00, 0x1f, 0x23, 0x26, 0x49, 0x4e, 0xf1, 0xf5, 0xf5, 0xff, 0xff, 0xff,
-  0xc7, 0xdb, 0xde, 0x4a, 0x8a, 0x95, 0x45, 0x86, 0x90, 0x45, 0x86, 0x90,
-  0x44, 0x85, 0x8f, 0x42, 0x83, 0x8e, 0x41, 0x83, 0x8d, 0x40, 0x82, 0x8c,
-  0x3f, 0x81, 0x8b, 0x3d, 0x80, 0x8a, 0x3c, 0x7e, 0x88, 0x3b, 0x7d, 0x88,
-  0x3a, 0x7c, 0x86, 0x38, 0x7b, 0x85, 0x37, 0x79, 0x84, 0x36, 0x78, 0x82,
-  0x34, 0x77, 0x81, 0x33, 0x75, 0x80, 0x31, 0x74, 0x7e, 0x31, 0x72, 0x7d,
-  0x2e, 0x71, 0x7b, 0x2d, 0x70, 0x7a, 0x2b, 0x6e, 0x78, 0x2a, 0x6d, 0x78,
-  0x29, 0x6b, 0x76, 0x27, 0x6a, 0x74, 0x26, 0x69, 0x73, 0x26, 0x68, 0x72,
-  0x25, 0x66, 0x71, 0x22, 0x65, 0x6f, 0x21, 0x63, 0x6f, 0x20, 0x62, 0x6d,
-  0x1f, 0x61, 0x6c, 0x1e, 0x60, 0x6a, 0x1d, 0x5f, 0x69, 0x1c, 0x5d, 0x68,
-  0x1b, 0x5c, 0x66, 0x19, 0x5b, 0x65, 0x19, 0x5a, 0x65, 0x18, 0x59, 0x63,
-  0x18, 0x58, 0x61, 0x17, 0x56, 0x61, 0x17, 0x55, 0x60, 0x16, 0x54, 0x5e,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x00, 0x1f, 0x25,
+  0x32, 0x55, 0x5a, 0xfa, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xaa, 0xc8, 0xcd,
+  0x48, 0x8a, 0x94, 0x47, 0x89, 0x93, 0x47, 0x88, 0x92, 0x47, 0x87, 0x91,
+  0x46, 0x87, 0x90, 0x44, 0x85, 0x8f, 0x43, 0x84, 0x8e, 0x42, 0x83, 0x8d,
+  0x41, 0x82, 0x8d, 0x3f, 0x81, 0x8b, 0x3d, 0x7f, 0x89, 0x3d, 0x7e, 0x89,
+  0x3b, 0x7d, 0x87, 0x3a, 0x7c, 0x86, 0x38, 0x7a, 0x84, 0x37, 0x79, 0x83,
+  0x36, 0x78, 0x82, 0x34, 0x76, 0x80, 0x32, 0x75, 0x7f, 0x31, 0x73, 0x7e,
+  0x2f, 0x72, 0x7c, 0x2e, 0x70, 0x7b, 0x2d, 0x70, 0x79, 0x2b, 0x6e, 0x78,
+  0x2a, 0x6c, 0x77, 0x28, 0x6b, 0x75, 0x27, 0x69, 0x73, 0x26, 0x69, 0x73,
+  0x25, 0x66, 0x71, 0x23, 0x66, 0x70, 0x22, 0x64, 0x6f, 0x21, 0x62, 0x6e,
+  0x20, 0x62, 0x6c, 0x1f, 0x60, 0x6b, 0x1e, 0x60, 0x6a, 0x1d, 0x5e, 0x68,
+  0x1c, 0x5c, 0x67, 0x1a, 0x5c, 0x65, 0x19, 0x5a, 0x65, 0x18, 0x59, 0x63,
+  0x18, 0x58, 0x61, 0x18, 0x57, 0x61, 0x17, 0x55, 0x60, 0x17, 0x55, 0x5f,
   0x16, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
+  0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58, 0x12, 0x4c, 0x56,
+  0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
+  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
+  0x0f, 0x46, 0x4f, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
+  0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
+  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
+  0x09, 0x2a, 0x2f, 0x1b, 0x42, 0x48, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x11, 0x64, 0x70, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
+  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
+  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
+  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
+  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
+  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
+  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
+  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
+  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
+  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
+  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
+  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
+  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
+  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
+  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
+  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
+  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
+  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
+  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
+  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x00, 0x22, 0x27, 0x1c, 0x41, 0x46,
+  0xde, 0xe5, 0xe6, 0xff, 0xff, 0xff, 0xb3, 0xce, 0xd2, 0x46, 0x88, 0x92,
+  0x45, 0x88, 0x92, 0x45, 0x87, 0x91, 0x43, 0x85, 0x8f, 0x43, 0x85, 0x8f,
+  0x42, 0x84, 0x8e, 0x41, 0x83, 0x8d, 0x40, 0x82, 0x8d, 0x3f, 0x82, 0x8b,
+  0x3d, 0x80, 0x8a, 0x3c, 0x7f, 0x89, 0x3b, 0x7e, 0x88, 0x3a, 0x7c, 0x87,
+  0x38, 0x7b, 0x85, 0x37, 0x7a, 0x84, 0x36, 0x79, 0x83, 0x34, 0x77, 0x81,
+  0x33, 0x76, 0x80, 0x31, 0x74, 0x7e, 0x31, 0x73, 0x7e, 0x30, 0x72, 0x7c,
+  0x2d, 0x71, 0x7a, 0x2c, 0x6f, 0x7a, 0x2b, 0x6e, 0x78, 0x29, 0x6c, 0x77,
+  0x28, 0x6b, 0x76, 0x27, 0x6a, 0x74, 0x26, 0x68, 0x72, 0x25, 0x67, 0x71,
+  0x24, 0x66, 0x71, 0x22, 0x65, 0x6f, 0x21, 0x63, 0x6f, 0x20, 0x62, 0x6d,
+  0x1f, 0x61, 0x6c, 0x1e, 0x60, 0x6a, 0x1d, 0x5f, 0x69, 0x1c, 0x5d, 0x68,
+  0x1b, 0x5c, 0x66, 0x19, 0x5b, 0x65, 0x18, 0x59, 0x64, 0x18, 0x59, 0x63,
+  0x18, 0x58, 0x61, 0x17, 0x56, 0x61, 0x17, 0x55, 0x60, 0x16, 0x54, 0x5e,
+  0x16, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x50, 0x5a,
   0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
   0x12, 0x4c, 0x55, 0x11, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
@@ -11195,7 +11195,7 @@
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
   0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x09, 0x28, 0x2d, 0x2b, 0x4f, 0x55, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11205,7 +11205,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x07, 0x5d, 0x69, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x37, 0x6d, 0x76, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
@@ -11235,84 +11235,20 @@
   0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x03, 0x28, 0x2e, 0x00, 0x22, 0x27,
-  0x12, 0x35, 0x3a, 0xcc, 0xd7, 0xd9, 0xff, 0xff, 0xff, 0xd6, 0xe5, 0xe7,
-  0x51, 0x8f, 0x99, 0x43, 0x86, 0x90, 0x41, 0x84, 0x8e, 0x41, 0x84, 0x8e,
-  0x40, 0x83, 0x8d, 0x3f, 0x82, 0x8c, 0x3e, 0x81, 0x8c, 0x3d, 0x80, 0x8a,
-  0x3c, 0x7f, 0x8a, 0x3c, 0x7e, 0x88, 0x39, 0x7c, 0x86, 0x38, 0x7b, 0x86,
-  0x37, 0x7a, 0x84, 0x36, 0x7a, 0x84, 0x34, 0x78, 0x82, 0x33, 0x76, 0x80,
-  0x32, 0x75, 0x80, 0x31, 0x73, 0x7e, 0x30, 0x73, 0x7d, 0x2e, 0x71, 0x7b,
-  0x2c, 0x70, 0x7a, 0x2b, 0x6e, 0x79, 0x29, 0x6d, 0x77, 0x28, 0x6c, 0x77,
-  0x27, 0x6a, 0x75, 0x26, 0x69, 0x74, 0x26, 0x68, 0x72, 0x24, 0x67, 0x71,
-  0x23, 0x65, 0x70, 0x21, 0x64, 0x6f, 0x20, 0x63, 0x6e, 0x1f, 0x61, 0x6d,
+  0x03, 0x2b, 0x31, 0x00, 0x24, 0x2a, 0x12, 0x36, 0x3b, 0xc7, 0xd4, 0xd6,
+  0xff, 0xff, 0xff, 0xb6, 0xd0, 0xd5, 0x47, 0x88, 0x93, 0x43, 0x86, 0x90,
+  0x41, 0x85, 0x90, 0x41, 0x84, 0x8f, 0x40, 0x83, 0x8e, 0x3f, 0x82, 0x8d,
+  0x3f, 0x82, 0x8c, 0x3e, 0x81, 0x8c, 0x3c, 0x80, 0x8b, 0x3c, 0x7f, 0x89,
+  0x3b, 0x7e, 0x89, 0x3a, 0x7d, 0x87, 0x38, 0x7c, 0x86, 0x37, 0x7a, 0x85,
+  0x36, 0x7a, 0x84, 0x34, 0x78, 0x83, 0x33, 0x77, 0x81, 0x32, 0x75, 0x80,
+  0x31, 0x74, 0x7f, 0x30, 0x73, 0x7d, 0x2f, 0x72, 0x7d, 0x2d, 0x70, 0x7b,
+  0x2b, 0x6f, 0x79, 0x2a, 0x6e, 0x79, 0x29, 0x6d, 0x77, 0x27, 0x6b, 0x76,
+  0x26, 0x69, 0x74, 0x26, 0x69, 0x73, 0x25, 0x67, 0x71, 0x24, 0x67, 0x71,
+  0x23, 0x65, 0x70, 0x20, 0x64, 0x6e, 0x1f, 0x62, 0x6d, 0x1e, 0x61, 0x6c,
   0x1e, 0x61, 0x6b, 0x1d, 0x5f, 0x69, 0x1c, 0x5e, 0x69, 0x1b, 0x5d, 0x67,
-  0x1a, 0x5b, 0x66, 0x19, 0x5b, 0x65, 0x18, 0x59, 0x64, 0x18, 0x59, 0x62,
-  0x18, 0x58, 0x61, 0x17, 0x56, 0x61, 0x16, 0x54, 0x5f, 0x16, 0x54, 0x5e,
+  0x1a, 0x5b, 0x66, 0x18, 0x5a, 0x64, 0x18, 0x59, 0x64, 0x18, 0x59, 0x62,
+  0x17, 0x57, 0x61, 0x17, 0x56, 0x61, 0x16, 0x54, 0x5f, 0x16, 0x54, 0x5e,
   0x15, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x50, 0x5a,
-  0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
-  0x12, 0x4c, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
-  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
-  0x0e, 0x45, 0x4e, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
-  0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x2a, 0x30, 0x19, 0x3f, 0x46, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x0c, 0x61, 0x6d, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2a, 0x30, 0x03, 0x29, 0x2f, 0x00, 0x25, 0x2a, 0x06, 0x2b, 0x2f,
-  0xa4, 0xb8, 0xba, 0xff, 0xff, 0xff, 0xde, 0xe9, 0xeb, 0x56, 0x92, 0x9b,
-  0x3f, 0x84, 0x8f, 0x3f, 0x83, 0x8e, 0x3e, 0x82, 0x8d, 0x3e, 0x82, 0x8d,
-  0x3d, 0x81, 0x8b, 0x3c, 0x80, 0x8b, 0x3c, 0x7f, 0x8a, 0x3b, 0x7f, 0x89,
-  0x3a, 0x7d, 0x88, 0x39, 0x7d, 0x87, 0x37, 0x7b, 0x85, 0x35, 0x79, 0x84,
-  0x34, 0x78, 0x83, 0x33, 0x78, 0x82, 0x32, 0x76, 0x81, 0x31, 0x74, 0x7f,
-  0x30, 0x74, 0x7e, 0x2f, 0x72, 0x7d, 0x2e, 0x71, 0x7c, 0x2c, 0x6f, 0x7a,
-  0x2a, 0x6f, 0x79, 0x29, 0x6d, 0x78, 0x28, 0x6d, 0x77, 0x26, 0x6a, 0x75,
-  0x26, 0x69, 0x74, 0x25, 0x68, 0x72, 0x24, 0x67, 0x71, 0x23, 0x66, 0x70,
-  0x22, 0x64, 0x70, 0x20, 0x64, 0x6e, 0x1f, 0x62, 0x6d, 0x1e, 0x61, 0x6c,
-  0x1d, 0x60, 0x6a, 0x1c, 0x5e, 0x69, 0x1b, 0x5e, 0x68, 0x1a, 0x5c, 0x67,
-  0x1a, 0x5b, 0x66, 0x18, 0x5a, 0x64, 0x18, 0x59, 0x63, 0x18, 0x59, 0x62,
-  0x17, 0x57, 0x61, 0x16, 0x55, 0x60, 0x16, 0x54, 0x5f, 0x15, 0x54, 0x5e,
-  0x15, 0x53, 0x5d, 0x15, 0x53, 0x5d, 0x13, 0x51, 0x5b, 0x13, 0x50, 0x5a,
   0x13, 0x4f, 0x59, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
   0x12, 0x4c, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x10, 0x47, 0x4f,
@@ -11322,8 +11258,8 @@
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x09, 0x29, 0x2e, 0x23, 0x49, 0x4f, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x30, 0x36, 0x0a, 0x2d, 0x32,
+  0x0a, 0x2e, 0x34, 0x56, 0x68, 0x6b, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11333,7 +11269,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x24, 0x6a, 0x74, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x73, 0x75, 0x75, 0x19, 0x67, 0x72, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
@@ -11363,21 +11299,21 @@
   0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
   0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
   0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x03, 0x2b, 0x31, 0x01, 0x27, 0x2d, 0x01, 0x26, 0x2c, 0x80, 0x9a, 0x9d,
-  0xff, 0xff, 0xff, 0xe1, 0xec, 0xed, 0x58, 0x94, 0x9d, 0x3e, 0x83, 0x8e,
-  0x3c, 0x82, 0x8d, 0x3c, 0x81, 0x8c, 0x3c, 0x80, 0x8b, 0x3b, 0x7f, 0x8a,
-  0x3b, 0x7f, 0x8a, 0x3a, 0x7e, 0x89, 0x39, 0x7d, 0x88, 0x38, 0x7d, 0x87,
-  0x37, 0x7b, 0x86, 0x36, 0x7b, 0x85, 0x34, 0x79, 0x84, 0x33, 0x78, 0x83,
-  0x32, 0x77, 0x82, 0x31, 0x76, 0x81, 0x30, 0x74, 0x7f, 0x2f, 0x73, 0x7e,
-  0x2e, 0x72, 0x7d, 0x2d, 0x71, 0x7c, 0x2c, 0x70, 0x7b, 0x2a, 0x6e, 0x79,
-  0x28, 0x6d, 0x77, 0x27, 0x6c, 0x77, 0x26, 0x6b, 0x75, 0x26, 0x6a, 0x75,
-  0x25, 0x68, 0x73, 0x24, 0x68, 0x72, 0x23, 0x66, 0x70, 0x21, 0x65, 0x6f,
+  0x00, 0x26, 0x2c, 0x0b, 0x31, 0x37, 0xad, 0xbf, 0xc2, 0xff, 0xff, 0xff,
+  0xb4, 0xcf, 0xd4, 0x44, 0x87, 0x92, 0x40, 0x84, 0x8f, 0x40, 0x84, 0x8f,
+  0x3e, 0x83, 0x8e, 0x3d, 0x82, 0x8d, 0x3d, 0x81, 0x8c, 0x3c, 0x81, 0x8b,
+  0x3c, 0x80, 0x8a, 0x3b, 0x7f, 0x8a, 0x3a, 0x7e, 0x89, 0x39, 0x7d, 0x88,
+  0x38, 0x7c, 0x87, 0x37, 0x7b, 0x86, 0x35, 0x7a, 0x84, 0x34, 0x78, 0x84,
+  0x33, 0x78, 0x82, 0x32, 0x77, 0x82, 0x31, 0x76, 0x80, 0x30, 0x74, 0x7e,
+  0x2f, 0x73, 0x7e, 0x2e, 0x71, 0x7c, 0x2d, 0x71, 0x7c, 0x2b, 0x6f, 0x7a,
+  0x29, 0x6e, 0x78, 0x28, 0x6d, 0x77, 0x27, 0x6c, 0x76, 0x26, 0x6a, 0x75,
+  0x26, 0x69, 0x74, 0x24, 0x68, 0x72, 0x23, 0x66, 0x70, 0x22, 0x65, 0x70,
   0x21, 0x64, 0x6f, 0x1f, 0x63, 0x6d, 0x1e, 0x61, 0x6d, 0x1d, 0x60, 0x6b,
-  0x1c, 0x5f, 0x6a, 0x1b, 0x5e, 0x68, 0x1a, 0x5d, 0x68, 0x1a, 0x5c, 0x67,
-  0x19, 0x5a, 0x65, 0x18, 0x5a, 0x63, 0x18, 0x59, 0x63, 0x17, 0x58, 0x62,
-  0x16, 0x56, 0x60, 0x16, 0x55, 0x60, 0x15, 0x54, 0x5f, 0x15, 0x54, 0x5e,
+  0x1c, 0x5f, 0x6a, 0x1c, 0x5e, 0x69, 0x1b, 0x5e, 0x68, 0x1a, 0x5c, 0x67,
+  0x19, 0x5a, 0x65, 0x18, 0x5a, 0x64, 0x18, 0x59, 0x63, 0x17, 0x58, 0x62,
+  0x17, 0x57, 0x61, 0x16, 0x55, 0x60, 0x16, 0x54, 0x5f, 0x15, 0x54, 0x5e,
   0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x51, 0x5b, 0x13, 0x50, 0x5a,
-  0x12, 0x4e, 0x58, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
+  0x13, 0x4f, 0x59, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57, 0x12, 0x4c, 0x56,
   0x11, 0x4c, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
   0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50, 0x0f, 0x46, 0x4e,
   0x0e, 0x45, 0x4e, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
@@ -11386,8 +11322,8 @@
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
   0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
   0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2d, 0x33,
-  0x09, 0x29, 0x2e, 0x45, 0x60, 0x64, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2d, 0x32, 0x09, 0x29, 0x2f,
+  0x36, 0x57, 0x5c, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11397,7 +11333,7 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x63, 0x73, 0x76, 0x0b, 0x60, 0x6d, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
+  0x75, 0x75, 0x75, 0x6f, 0x74, 0x75, 0x23, 0x6a, 0x74, 0x07, 0x5d, 0x69,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
   0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
@@ -11409,113 +11345,48 @@
   0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
   0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
   0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
-  0x06, 0x58, 0x63, 0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
-  0x06, 0x57, 0x62, 0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61,
-  0x06, 0x55, 0x61, 0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60,
-  0x06, 0x54, 0x5f, 0x06, 0x54, 0x5f, 0x06, 0x53, 0x5e, 0x06, 0x53, 0x5e,
-  0x05, 0x53, 0x5e, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5c, 0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a,
-  0x05, 0x4f, 0x5a, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58,
-  0x05, 0x4d, 0x57, 0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4c, 0x56,
-  0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53,
-  0x05, 0x48, 0x52, 0x05, 0x48, 0x51, 0x05, 0x47, 0x51, 0x05, 0x47, 0x50,
-  0x05, 0x46, 0x4f, 0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4d,
-  0x04, 0x43, 0x4c, 0x04, 0x42, 0x4b, 0x04, 0x41, 0x4a, 0x04, 0x40, 0x49,
-  0x04, 0x3f, 0x48, 0x04, 0x3e, 0x47, 0x04, 0x3e, 0x46, 0x04, 0x3d, 0x45,
-  0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43, 0x04, 0x3a, 0x42, 0x04, 0x39, 0x41,
-  0x04, 0x38, 0x3f, 0x04, 0x37, 0x3e, 0x04, 0x36, 0x3d, 0x04, 0x35, 0x3c,
-  0x04, 0x33, 0x3b, 0x03, 0x33, 0x3a, 0x03, 0x32, 0x38, 0x03, 0x31, 0x37,
-  0x03, 0x2f, 0x36, 0x03, 0x2e, 0x34, 0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32,
-  0x01, 0x29, 0x2f, 0x00, 0x23, 0x29, 0x69, 0x87, 0x8b, 0xff, 0xff, 0xff,
-  0xe0, 0xec, 0xed, 0x55, 0x93, 0x9c, 0x3b, 0x81, 0x8c, 0x3b, 0x81, 0x8b,
-  0x3a, 0x81, 0x8b, 0x39, 0x7f, 0x8a, 0x39, 0x7e, 0x89, 0x38, 0x7e, 0x89,
-  0x37, 0x7d, 0x87, 0x37, 0x7c, 0x87, 0x36, 0x7c, 0x87, 0x35, 0x7b, 0x85,
-  0x34, 0x7a, 0x85, 0x33, 0x79, 0x83, 0x31, 0x77, 0x82, 0x31, 0x76, 0x81,
-  0x30, 0x75, 0x80, 0x2f, 0x75, 0x7f, 0x2e, 0x73, 0x7e, 0x2d, 0x72, 0x7c,
-  0x2c, 0x71, 0x7c, 0x2b, 0x70, 0x7a, 0x2a, 0x6f, 0x7a, 0x28, 0x6d, 0x78,
-  0x26, 0x6c, 0x76, 0x26, 0x6b, 0x76, 0x25, 0x6a, 0x74, 0x24, 0x68, 0x74,
-  0x23, 0x67, 0x72, 0x22, 0x66, 0x71, 0x21, 0x65, 0x6f, 0x20, 0x64, 0x6e,
-  0x1f, 0x62, 0x6e, 0x1e, 0x62, 0x6d, 0x1d, 0x61, 0x6c, 0x1c, 0x5f, 0x6b,
-  0x1b, 0x5f, 0x69, 0x1a, 0x5d, 0x68, 0x1a, 0x5d, 0x68, 0x19, 0x5b, 0x66,
-  0x19, 0x5a, 0x64, 0x18, 0x5a, 0x63, 0x17, 0x58, 0x63, 0x17, 0x58, 0x62,
-  0x16, 0x56, 0x60, 0x16, 0x55, 0x60, 0x15, 0x54, 0x5f, 0x15, 0x54, 0x5e,
-  0x14, 0x52, 0x5c, 0x14, 0x52, 0x5c, 0x13, 0x51, 0x5b, 0x12, 0x4f, 0x59,
-  0x12, 0x4e, 0x58, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57, 0x11, 0x4c, 0x56,
-  0x11, 0x4c, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
-  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x0f, 0x46, 0x4f, 0x0f, 0x46, 0x4e,
-  0x0e, 0x45, 0x4e, 0x0e, 0x44, 0x4d, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
-  0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
-  0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
-  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
-  0x0a, 0x31, 0x37, 0x0a, 0x31, 0x37, 0x0a, 0x2f, 0x35, 0x09, 0x28, 0x2d,
-  0x20, 0x46, 0x4c, 0x73, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x56, 0x72, 0x76, 0x0c, 0x61, 0x6d, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67,
-  0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5b, 0x67, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66,
-  0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x5a, 0x66, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x59, 0x65,
-  0x06, 0x59, 0x65, 0x06, 0x59, 0x65, 0x06, 0x58, 0x64, 0x06, 0x58, 0x64,
-  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63,
+  0x06, 0x58, 0x64, 0x06, 0x58, 0x63, 0x06, 0x58, 0x63, 0x06, 0x57, 0x63,
   0x06, 0x57, 0x63, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62, 0x06, 0x57, 0x62,
   0x06, 0x56, 0x62, 0x06, 0x56, 0x61, 0x06, 0x56, 0x61, 0x06, 0x55, 0x61,
   0x06, 0x55, 0x60, 0x06, 0x55, 0x60, 0x06, 0x54, 0x60, 0x06, 0x54, 0x5f,
   0x06, 0x54, 0x5f, 0x06, 0x53, 0x5f, 0x05, 0x53, 0x5e, 0x05, 0x53, 0x5e,
   0x05, 0x53, 0x5d, 0x05, 0x52, 0x5d, 0x05, 0x52, 0x5c, 0x05, 0x51, 0x5c,
-  0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x50, 0x5a, 0x05, 0x4f, 0x5a,
+  0x05, 0x51, 0x5b, 0x05, 0x50, 0x5b, 0x05, 0x4f, 0x5a, 0x05, 0x4f, 0x5a,
   0x05, 0x4e, 0x59, 0x05, 0x4e, 0x58, 0x05, 0x4e, 0x58, 0x05, 0x4d, 0x57,
   0x05, 0x4d, 0x57, 0x05, 0x4c, 0x56, 0x05, 0x4b, 0x55, 0x05, 0x4b, 0x55,
   0x05, 0x4a, 0x54, 0x05, 0x4a, 0x54, 0x05, 0x49, 0x53, 0x05, 0x48, 0x51,
   0x05, 0x48, 0x51, 0x05, 0x47, 0x50, 0x05, 0x46, 0x50, 0x05, 0x46, 0x4f,
-  0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4c, 0x04, 0x43, 0x4b,
-  0x04, 0x42, 0x4b, 0x04, 0x41, 0x49, 0x04, 0x40, 0x49, 0x04, 0x3f, 0x48,
-  0x04, 0x3e, 0x47, 0x04, 0x3d, 0x45, 0x04, 0x3d, 0x45, 0x04, 0x3c, 0x44,
-  0x04, 0x3b, 0x43, 0x04, 0x39, 0x41, 0x04, 0x38, 0x40, 0x04, 0x38, 0x3f,
-  0x04, 0x36, 0x3e, 0x04, 0x35, 0x3d, 0x04, 0x34, 0x3c, 0x04, 0x33, 0x3a,
-  0x03, 0x32, 0x39, 0x03, 0x31, 0x38, 0x03, 0x30, 0x36, 0x03, 0x2f, 0x35,
-  0x03, 0x2e, 0x34, 0x03, 0x2c, 0x32, 0x03, 0x2b, 0x31, 0x03, 0x29, 0x2f,
-  0x00, 0x25, 0x2a, 0x5a, 0x7a, 0x7e, 0xff, 0xff, 0xff, 0xdc, 0xe9, 0xeb,
-  0x52, 0x90, 0x9a, 0x38, 0x7f, 0x8a, 0x38, 0x7f, 0x8a, 0x37, 0x7e, 0x89,
-  0x37, 0x7e, 0x89, 0x36, 0x7c, 0x88, 0x36, 0x7c, 0x88, 0x35, 0x7b, 0x86,
-  0x34, 0x7a, 0x85, 0x34, 0x7a, 0x84, 0x33, 0x79, 0x83, 0x32, 0x77, 0x83,
-  0x31, 0x77, 0x81, 0x30, 0x75, 0x81, 0x30, 0x75, 0x80, 0x2f, 0x74, 0x7e,
-  0x2e, 0x73, 0x7e, 0x2d, 0x72, 0x7c, 0x2c, 0x71, 0x7c, 0x2b, 0x70, 0x7a,
-  0x2a, 0x6e, 0x79, 0x29, 0x6d, 0x78, 0x27, 0x6d, 0x77, 0x26, 0x6b, 0x76,
-  0x26, 0x6a, 0x75, 0x25, 0x69, 0x73, 0x24, 0x68, 0x73, 0x23, 0x67, 0x71,
-  0x22, 0x65, 0x70, 0x21, 0x64, 0x6f, 0x1f, 0x62, 0x6d, 0x1e, 0x61, 0x6c,
-  0x1d, 0x60, 0x6b, 0x1c, 0x5f, 0x6a, 0x1c, 0x5f, 0x6a, 0x1b, 0x5e, 0x68,
-  0x1a, 0x5c, 0x67, 0x19, 0x5a, 0x65, 0x19, 0x5a, 0x65, 0x18, 0x59, 0x63,
-  0x18, 0x59, 0x62, 0x17, 0x57, 0x61, 0x17, 0x56, 0x61, 0x16, 0x55, 0x5f,
-  0x16, 0x54, 0x5e, 0x15, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x13, 0x50, 0x5a,
-  0x13, 0x50, 0x5a, 0x13, 0x4f, 0x59, 0x12, 0x4e, 0x57, 0x12, 0x4d, 0x57,
-  0x12, 0x4c, 0x56, 0x11, 0x4b, 0x55, 0x10, 0x4b, 0x54, 0x10, 0x4a, 0x53,
-  0x10, 0x4a, 0x53, 0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50,
-  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0e, 0x43, 0x4c, 0x0e, 0x43, 0x4b,
-  0x0e, 0x43, 0x4b, 0x0e, 0x42, 0x4a, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48,
-  0x0d, 0x3f, 0x47, 0x0d, 0x3e, 0x46, 0x0d, 0x3e, 0x45, 0x0d, 0x3c, 0x44,
+  0x05, 0x45, 0x4e, 0x05, 0x44, 0x4d, 0x05, 0x43, 0x4c, 0x04, 0x42, 0x4b,
+  0x04, 0x42, 0x4a, 0x04, 0x41, 0x49, 0x04, 0x40, 0x49, 0x04, 0x3f, 0x48,
+  0x04, 0x3e, 0x47, 0x04, 0x3d, 0x45, 0x04, 0x3c, 0x44, 0x04, 0x3b, 0x43,
+  0x04, 0x3a, 0x42, 0x04, 0x39, 0x41, 0x04, 0x38, 0x40, 0x04, 0x38, 0x3f,
+  0x04, 0x36, 0x3e, 0x04, 0x35, 0x3d, 0x04, 0x34, 0x3b, 0x03, 0x33, 0x3a,
+  0x03, 0x32, 0x38, 0x03, 0x31, 0x38, 0x03, 0x30, 0x36, 0x03, 0x2e, 0x35,
+  0x03, 0x2d, 0x33, 0x03, 0x2c, 0x32, 0x03, 0x2b, 0x31, 0x01, 0x28, 0x2e,
+  0x08, 0x30, 0x35, 0x9d, 0xb2, 0xb5, 0xff, 0xff, 0xff, 0xac, 0xca, 0xce,
+  0x40, 0x85, 0x8f, 0x3c, 0x82, 0x8d, 0x3c, 0x81, 0x8c, 0x3c, 0x81, 0x8c,
+  0x3c, 0x80, 0x8b, 0x3b, 0x7f, 0x8a, 0x3a, 0x7e, 0x89, 0x3a, 0x7e, 0x88,
+  0x39, 0x7d, 0x88, 0x38, 0x7c, 0x86, 0x37, 0x7b, 0x86, 0x36, 0x7a, 0x85,
+  0x34, 0x79, 0x84, 0x33, 0x78, 0x83, 0x32, 0x77, 0x82, 0x31, 0x76, 0x80,
+  0x31, 0x75, 0x80, 0x30, 0x74, 0x7e, 0x2f, 0x73, 0x7e, 0x2e, 0x71, 0x7c,
+  0x2d, 0x70, 0x7b, 0x2c, 0x6f, 0x7a, 0x2a, 0x6e, 0x79, 0x28, 0x6d, 0x77,
+  0x27, 0x6b, 0x75, 0x26, 0x69, 0x74, 0x26, 0x69, 0x73, 0x25, 0x68, 0x72,
+  0x24, 0x67, 0x71, 0x23, 0x65, 0x70, 0x21, 0x63, 0x6f, 0x20, 0x63, 0x6d,
+  0x1f, 0x61, 0x6d, 0x1e, 0x61, 0x6b, 0x1d, 0x60, 0x6a, 0x1c, 0x5e, 0x69,
+  0x1b, 0x5d, 0x67, 0x1b, 0x5c, 0x66, 0x1a, 0x5b, 0x66, 0x18, 0x59, 0x63,
+  0x18, 0x58, 0x63, 0x18, 0x57, 0x61, 0x17, 0x56, 0x60, 0x17, 0x55, 0x60,
+  0x16, 0x54, 0x5e, 0x16, 0x53, 0x5d, 0x14, 0x52, 0x5c, 0x14, 0x51, 0x5b,
+  0x13, 0x50, 0x5a, 0x13, 0x4f, 0x59, 0x13, 0x4f, 0x58, 0x13, 0x4e, 0x58,
+  0x12, 0x4c, 0x56, 0x11, 0x4b, 0x54, 0x11, 0x4b, 0x54, 0x11, 0x4a, 0x53,
+  0x10, 0x49, 0x52, 0x10, 0x48, 0x51, 0x10, 0x48, 0x51, 0x10, 0x47, 0x50,
+  0x0f, 0x46, 0x4f, 0x0f, 0x45, 0x4e, 0x0f, 0x44, 0x4d, 0x0e, 0x43, 0x4b,
+  0x0e, 0x43, 0x4b, 0x0e, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
+  0x0d, 0x3f, 0x47, 0x0d, 0x3e, 0x45, 0x0d, 0x3d, 0x45, 0x0d, 0x3c, 0x44,
   0x0d, 0x3b, 0x43, 0x0c, 0x3b, 0x42, 0x0c, 0x3a, 0x41, 0x0c, 0x39, 0x40,
-  0x0c, 0x38, 0x3f, 0x0c, 0x38, 0x3e, 0x0c, 0x37, 0x3d, 0x0b, 0x36, 0x3c,
-  0x0b, 0x35, 0x3c, 0x0b, 0x34, 0x3b, 0x0b, 0x33, 0x3a, 0x0b, 0x32, 0x39,
-  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x2f, 0x35, 0x0a, 0x2e, 0x34,
-  0x0a, 0x2d, 0x33, 0x0a, 0x2c, 0x32, 0x09, 0x2b, 0x31, 0x21, 0x46, 0x4c,
-  0x69, 0x70, 0x71, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x0c, 0x38, 0x3f, 0x0c, 0x37, 0x3e, 0x0c, 0x36, 0x3d, 0x0b, 0x35, 0x3c,
+  0x0b, 0x34, 0x3b, 0x0b, 0x34, 0x3a, 0x0b, 0x33, 0x39, 0x0b, 0x32, 0x38,
+  0x0a, 0x31, 0x37, 0x0a, 0x30, 0x36, 0x0a, 0x30, 0x36, 0x0a, 0x2e, 0x34,
+  0x0a, 0x2d, 0x32, 0x0a, 0x2c, 0x32, 0x12, 0x37, 0x3e, 0x3e, 0x5c, 0x61,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11525,60 +11396,189 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x69, 0x74, 0x75, 0x33, 0x6d, 0x75,
-  0x14, 0x65, 0x71, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
-  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
-  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
-  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
-  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e,
-  0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6e, 0x0f, 0x62, 0x6d,
-  0x0f, 0x62, 0x6d, 0x0f, 0x62, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d,
-  0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d,
-  0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6d, 0x0f, 0x61, 0x6c,
-  0x0f, 0x61, 0x6c, 0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c,
-  0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c, 0x0f, 0x60, 0x6c,
-  0x0f, 0x60, 0x6b, 0x0f, 0x5f, 0x6b, 0x0f, 0x5f, 0x6b, 0x0f, 0x5f, 0x6b,
-  0x0f, 0x5f, 0x6b, 0x0f, 0x5f, 0x6b, 0x0f, 0x5f, 0x6a, 0x0f, 0x5f, 0x6a,
-  0x0f, 0x5e, 0x6a, 0x0f, 0x5e, 0x69, 0x0f, 0x5e, 0x69, 0x0f, 0x5e, 0x69,
-  0x0f, 0x5d, 0x69, 0x0d, 0x5d, 0x68, 0x0d, 0x5d, 0x68, 0x0d, 0x5d, 0x68,
-  0x0d, 0x5c, 0x68, 0x0d, 0x5c, 0x67, 0x0d, 0x5c, 0x67, 0x0d, 0x5c, 0x67,
-  0x0d, 0x5b, 0x66, 0x0d, 0x5b, 0x66, 0x0d, 0x5b, 0x66, 0x0d, 0x5a, 0x65,
-  0x0d, 0x5a, 0x65, 0x0d, 0x59, 0x64, 0x0e, 0x59, 0x64, 0x0e, 0x59, 0x63,
-  0x0e, 0x59, 0x63, 0x0e, 0x59, 0x62, 0x0e, 0x59, 0x62, 0x0e, 0x57, 0x61,
-  0x0e, 0x58, 0x60, 0x0f, 0x57, 0x5f, 0x0f, 0x57, 0x5f, 0x0e, 0x56, 0x5f,
-  0x0d, 0x56, 0x5f, 0x0d, 0x55, 0x5f, 0x0d, 0x54, 0x5e, 0x0d, 0x54, 0x5d,
-  0x0e, 0x53, 0x5e, 0x0e, 0x53, 0x5d, 0x0e, 0x52, 0x5c, 0x0e, 0x52, 0x5c,
-  0x0e, 0x51, 0x5b, 0x0e, 0x52, 0x5a, 0x0e, 0x51, 0x5a, 0x0e, 0x4f, 0x58,
-  0x0e, 0x4f, 0x57, 0x0e, 0x4e, 0x56, 0x0e, 0x4d, 0x56, 0x0f, 0x4c, 0x56,
-  0x0f, 0x4c, 0x55, 0x0d, 0x4b, 0x53, 0x0d, 0x4a, 0x53, 0x0d, 0x4a, 0x51,
-  0x0e, 0x4a, 0x51, 0x0e, 0x49, 0x51, 0x0d, 0x48, 0x50, 0x0d, 0x47, 0x4f,
-  0x0d, 0x46, 0x4e, 0x0d, 0x46, 0x4d, 0x0d, 0x44, 0x4b, 0x0d, 0x43, 0x4b,
-  0x0d, 0x42, 0x4b, 0x0d, 0x41, 0x49, 0x0d, 0x40, 0x48, 0x0d, 0x3f, 0x47,
-  0x0d, 0x3f, 0x46, 0x0c, 0x3e, 0x45, 0x0c, 0x3d, 0x43, 0x09, 0x37, 0x3f,
-  0x41, 0x69, 0x6e, 0xd7, 0xe4, 0xe6, 0xc4, 0xd7, 0xda, 0x5b, 0x91, 0x98,
-  0x46, 0x81, 0x8a, 0x46, 0x80, 0x89, 0x46, 0x80, 0x89, 0x46, 0x80, 0x89,
-  0x45, 0x80, 0x89, 0x45, 0x80, 0x89, 0x43, 0x7e, 0x88, 0x43, 0x7d, 0x86,
-  0x43, 0x7d, 0x86, 0x42, 0x7c, 0x85, 0x41, 0x7b, 0x84, 0x41, 0x7b, 0x84,
-  0x40, 0x7a, 0x84, 0x3f, 0x79, 0x83, 0x3e, 0x78, 0x82, 0x3d, 0x78, 0x81,
-  0x3c, 0x77, 0x80, 0x3b, 0x76, 0x7f, 0x3b, 0x76, 0x7f, 0x3a, 0x74, 0x7d,
-  0x39, 0x74, 0x7d, 0x38, 0x71, 0x7b, 0x37, 0x71, 0x7b, 0x36, 0x70, 0x7a,
-  0x35, 0x6f, 0x79, 0x34, 0x6f, 0x77, 0x33, 0x6f, 0x77, 0x32, 0x6c, 0x76,
-  0x32, 0x6b, 0x75, 0x31, 0x6b, 0x75, 0x2f, 0x69, 0x73, 0x2f, 0x69, 0x71,
-  0x2e, 0x68, 0x71, 0x2d, 0x68, 0x70, 0x2d, 0x67, 0x6f, 0x2c, 0x65, 0x6f,
-  0x2a, 0x64, 0x6d, 0x2a, 0x64, 0x6c, 0x29, 0x63, 0x6c, 0x29, 0x62, 0x6b,
-  0x28, 0x62, 0x6a, 0x27, 0x60, 0x69, 0x27, 0x60, 0x69, 0x27, 0x60, 0x69,
-  0x26, 0x5e, 0x67, 0x26, 0x5e, 0x67, 0x26, 0x5e, 0x65, 0x25, 0x5d, 0x64,
-  0x25, 0x5d, 0x64, 0x24, 0x5b, 0x63, 0x23, 0x5a, 0x63, 0x23, 0x59, 0x63,
-  0x23, 0x59, 0x62, 0x23, 0x58, 0x61, 0x22, 0x58, 0x61, 0x22, 0x57, 0x60,
-  0x22, 0x57, 0x60, 0x22, 0x56, 0x5f, 0x22, 0x56, 0x5f, 0x22, 0x55, 0x5d,
-  0x21, 0x55, 0x5d, 0x20, 0x53, 0x5b, 0x20, 0x52, 0x5b, 0x20, 0x52, 0x5b,
-  0x20, 0x52, 0x5b, 0x20, 0x52, 0x5a, 0x1f, 0x51, 0x59, 0x1f, 0x51, 0x59,
-  0x1f, 0x50, 0x58, 0x1e, 0x4f, 0x57, 0x1e, 0x4f, 0x57, 0x1e, 0x4d, 0x55,
-  0x1e, 0x4d, 0x55, 0x1e, 0x4d, 0x54, 0x1e, 0x4c, 0x54, 0x1d, 0x4c, 0x53,
-  0x1d, 0x4b, 0x52, 0x1c, 0x4a, 0x51, 0x1d, 0x4a, 0x51, 0x1d, 0x49, 0x50,
-  0x1d, 0x48, 0x4f, 0x1c, 0x47, 0x4e, 0x1c, 0x47, 0x4e, 0x1c, 0x46, 0x4d,
-  0x1c, 0x46, 0x4c, 0x1b, 0x45, 0x4b, 0x1b, 0x44, 0x4b, 0x1b, 0x43, 0x4a,
-  0x1b, 0x43, 0x49, 0x26, 0x4c, 0x52, 0x49, 0x62, 0x67, 0x72, 0x73, 0x73,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x5b, 0x73, 0x76,
+  0x39, 0x6e, 0x76, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
+  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
+  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
+  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
+  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
+  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
+  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
+  0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75, 0x2d, 0x6c, 0x75,
+  0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74,
+  0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74,
+  0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x74, 0x2d, 0x6b, 0x73, 0x2d, 0x6b, 0x73,
+  0x2d, 0x6b, 0x73, 0x2d, 0x6b, 0x73, 0x2c, 0x6a, 0x73, 0x2c, 0x69, 0x72,
+  0x2c, 0x69, 0x72, 0x2c, 0x69, 0x72, 0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72,
+  0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72,
+  0x2d, 0x69, 0x72, 0x2d, 0x69, 0x72, 0x2d, 0x69, 0x71, 0x2d, 0x69, 0x71,
+  0x2c, 0x68, 0x71, 0x2c, 0x68, 0x71, 0x2c, 0x68, 0x72, 0x2c, 0x68, 0x72,
+  0x2c, 0x68, 0x70, 0x2c, 0x68, 0x70, 0x2c, 0x67, 0x70, 0x2c, 0x67, 0x70,
+  0x2c, 0x67, 0x70, 0x2d, 0x67, 0x70, 0x2d, 0x67, 0x6f, 0x2c, 0x67, 0x6f,
+  0x2d, 0x67, 0x6f, 0x2d, 0x66, 0x6f, 0x2d, 0x66, 0x6f, 0x2e, 0x67, 0x6f,
+  0x2e, 0x67, 0x6f, 0x2e, 0x67, 0x6f, 0x2e, 0x67, 0x6f, 0x2d, 0x67, 0x6f,
+  0x2e, 0x66, 0x6f, 0x2e, 0x66, 0x6e, 0x2e, 0x66, 0x6e, 0x2e, 0x66, 0x6e,
+  0x2f, 0x66, 0x6d, 0x2e, 0x65, 0x6e, 0x2f, 0x65, 0x6e, 0x2f, 0x65, 0x6e,
+  0x30, 0x65, 0x6d, 0x2f, 0x65, 0x6c, 0x30, 0x65, 0x6c, 0x31, 0x65, 0x6c,
+  0x30, 0x64, 0x6c, 0x30, 0x64, 0x6b, 0x31, 0x64, 0x6c, 0x31, 0x64, 0x6b,
+  0x31, 0x64, 0x6b, 0x31, 0x63, 0x6b, 0x31, 0x63, 0x6a, 0x31, 0x62, 0x6a,
+  0x31, 0x62, 0x6a, 0x31, 0x62, 0x69, 0x31, 0x61, 0x69, 0x32, 0x61, 0x69,
+  0x31, 0x61, 0x69, 0x31, 0x61, 0x67, 0x31, 0x60, 0x66, 0x31, 0x60, 0x66,
+  0x31, 0x5f, 0x66, 0x31, 0x5f, 0x65, 0x31, 0x5f, 0x65, 0x30, 0x5e, 0x64,
+  0x30, 0x5d, 0x63, 0x30, 0x5d, 0x63, 0x30, 0x5b, 0x62, 0x2c, 0x56, 0x5d,
+  0x69, 0x89, 0x8d, 0xaf, 0xc2, 0xc4, 0x9d, 0xb4, 0xb7, 0x67, 0x89, 0x8f,
+  0x64, 0x87, 0x8c, 0x64, 0x87, 0x8c, 0x63, 0x87, 0x8c, 0x63, 0x87, 0x8c,
+  0x62, 0x85, 0x8b, 0x62, 0x85, 0x8b, 0x62, 0x84, 0x8a, 0x62, 0x84, 0x8a,
+  0x61, 0x84, 0x8a, 0x60, 0x83, 0x88, 0x60, 0x83, 0x88, 0x5f, 0x83, 0x88,
+  0x5e, 0x81, 0x87, 0x5e, 0x81, 0x86, 0x5d, 0x80, 0x86, 0x5c, 0x7f, 0x85,
+  0x5b, 0x7f, 0x85, 0x5a, 0x7e, 0x84, 0x59, 0x7d, 0x82, 0x59, 0x7c, 0x82,
+  0x58, 0x7c, 0x82, 0x57, 0x7b, 0x81, 0x57, 0x7b, 0x80, 0x55, 0x7a, 0x7f,
+  0x54, 0x79, 0x7e, 0x54, 0x77, 0x7d, 0x54, 0x77, 0x7d, 0x52, 0x77, 0x7c,
+  0x51, 0x76, 0x7b, 0x50, 0x75, 0x7b, 0x4f, 0x74, 0x79, 0x4f, 0x73, 0x79,
+  0x4e, 0x72, 0x78, 0x4d, 0x72, 0x78, 0x4c, 0x71, 0x77, 0x4b, 0x70, 0x76,
+  0x4b, 0x70, 0x76, 0x4a, 0x70, 0x75, 0x49, 0x6f, 0x75, 0x49, 0x6e, 0x74,
+  0x48, 0x6d, 0x73, 0x47, 0x6c, 0x71, 0x47, 0x6c, 0x71, 0x46, 0x6b, 0x71,
+  0x46, 0x6b, 0x71, 0x45, 0x6a, 0x70, 0x45, 0x6a, 0x70, 0x45, 0x6a, 0x70,
+  0x45, 0x68, 0x6e, 0x45, 0x68, 0x6e, 0x45, 0x68, 0x6e, 0x44, 0x68, 0x6d,
+  0x44, 0x68, 0x6d, 0x43, 0x67, 0x6c, 0x43, 0x67, 0x6c, 0x42, 0x65, 0x6c,
+  0x42, 0x65, 0x6c, 0x42, 0x65, 0x6b, 0x42, 0x65, 0x6b, 0x41, 0x65, 0x6b,
+  0x41, 0x64, 0x6a, 0x41, 0x64, 0x6a, 0x40, 0x63, 0x69, 0x40, 0x63, 0x69,
+  0x40, 0x63, 0x69, 0x3f, 0x63, 0x68, 0x3f, 0x63, 0x68, 0x3f, 0x62, 0x68,
+  0x3f, 0x61, 0x67, 0x3f, 0x61, 0x67, 0x3f, 0x61, 0x67, 0x3f, 0x60, 0x67,
+  0x3e, 0x60, 0x65, 0x3e, 0x60, 0x65, 0x3e, 0x60, 0x65, 0x3e, 0x5f, 0x65,
+  0x3e, 0x5f, 0x65, 0x3d, 0x5f, 0x64, 0x3d, 0x5f, 0x64, 0x3d, 0x5e, 0x64,
+  0x3d, 0x5e, 0x63, 0x3d, 0x5e, 0x63, 0x3d, 0x5d, 0x63, 0x3d, 0x5d, 0x63,
+  0x3c, 0x5c, 0x62, 0x3b, 0x5c, 0x61, 0x3c, 0x5b, 0x60, 0x3c, 0x5b, 0x60,
+  0x3c, 0x5b, 0x60, 0x4a, 0x63, 0x67, 0x67, 0x70, 0x71, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88,
+  0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+  0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+  0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+  0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+  0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+  0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+  0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+  0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85,
+  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11608,32 +11608,31 @@
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
   0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85,
   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
-  0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
   0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85,
   0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
+  0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
   0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11669,29 +11668,30 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
@@ -11733,98 +11733,34 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
-  0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
-  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
-  0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+  0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+  0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82,
   0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11865,28 +11801,28 @@
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81,
   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
   0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
   0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11928,30 +11864,94 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f,
   0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
   0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
+  0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
   0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -11992,28 +11992,28 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
   0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -12058,92 +12058,28 @@
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
-  0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
   0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
   0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
   0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
   0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
-  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d,
+  0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c,
   0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
+  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -12185,89 +12121,153 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
+  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
-  0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
   0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b,
-  0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -12312,91 +12312,218 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a,
-  0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -12440,280 +12567,26 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78,
-  0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -12761,20 +12634,20 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+  0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
@@ -12826,89 +12699,22 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
   0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
-  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
-  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -12962,6 +12768,137 @@
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+  0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
   0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
@@ -13024,6 +12961,69 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76,
+  0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
+  0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
@@ -16386,4 +16386,4 @@
   0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
   0x75, 0x75, 0x75
 };
-unsigned int ___lunarg_ppm_len = 196623;
+unsigned int lunarg_ppm_len = 196623;
diff --git a/demos/cube.c b/demos/cube.c
index 082ed61..17617e5 100644
--- a/demos/cube.c
+++ b/demos/cube.c
@@ -1,25 +1,26 @@
-    /*
- * Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 LunarG, Inc.
- *
- * Licensed under the Apache 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
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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: Chia-I Wu <olv@lunarg.com>
- * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
- * Author: Ian Elliott <ian@LunarG.com>
- * Author: Jon Ashburn <jon@lunarg.com>
- */
+/*
+* Copyright (c) 2015-2016 The Khronos Group Inc.
+* Copyright (c) 2015-2016 Valve Corporation
+* Copyright (c) 2015-2016 LunarG, Inc.
+*
+* Licensed under the Apache 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
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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: Chia-I Wu <olv@lunarg.com>
+* Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+* Author: Ian Elliott <ian@LunarG.com>
+* Author: Jon Ashburn <jon@lunarg.com>
+* Author: Gwan-gyeong Mun <elongbug@gmail.com>
+*/
 
 #define _GNU_SOURCE
 #include <stdio.h>
@@ -28,7 +29,7 @@
 #include <stdbool.h>
 #include <assert.h>
 #include <signal.h>
-#ifdef __linux__
+#if defined(__linux__) && !defined(ANDROID)
 #include <X11/Xutil.h>
 #endif
 
@@ -58,10 +59,17 @@
 #define U_ASSERT_ONLY
 #endif
 
+#if defined(__GNUC__)
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
+
 #ifdef _WIN32
 #define ERR_EXIT(err_msg, err_class)                                           \
     do {                                                                       \
-        MessageBox(NULL, err_msg, err_class, MB_OK);                           \
+        if (!demo->suppress_popups)                                            \
+            MessageBox(NULL, err_msg, err_class, MB_OK);                       \
         exit(1);                                                               \
     } while (0)
 
@@ -143,21 +151,6 @@
 // Mesh and VertexFormat Data
 //--------------------------------------------------------------------------------------
 // clang-format off
-struct Vertex
-{
-    float     posX, posY, posZ, posW;    // Position data
-    float     r, g, b, a;                // Color
-};
-
-struct VertexPosTex
-{
-    float     posX, posY, posZ, posW;    // Position data
-    float     u, v, s, t;                // Texcoord
-};
-
-#define XYZ1(_x_, _y_, _z_)         (_x_), (_y_), (_z_), 1.f
-#define UV(_u_, _v_)                (_u_), (_v_), 0.f, 1.f
-
 static const float g_vertex_buffer_data[] = {
     -1.0f,-1.0f,-1.0f,  // -X side
     -1.0f,-1.0f, 1.0f,
@@ -203,47 +196,47 @@
 };
 
 static const float g_uv_buffer_data[] = {
-    0.0f, 0.0f,  // -X side
+    0.0f, 1.0f,  // -X side
+    1.0f, 1.0f,
     1.0f, 0.0f,
-    1.0f, 1.0f,
-    1.0f, 1.0f,
-    0.0f, 1.0f,
-    0.0f, 0.0f,
-
-    1.0f, 0.0f,  // -Z side
-    0.0f, 1.0f,
-    0.0f, 0.0f,
     1.0f, 0.0f,
-    1.0f, 1.0f,
-    0.0f, 1.0f,
-
-    1.0f, 1.0f,  // -Y side
-    1.0f, 0.0f,
-    0.0f, 0.0f,
-    1.0f, 1.0f,
     0.0f, 0.0f,
     0.0f, 1.0f,
 
-    1.0f, 1.0f,  // +Y side
+    1.0f, 1.0f,  // -Z side
+    0.0f, 0.0f,
+    0.0f, 1.0f,
+    1.0f, 1.0f,
+    1.0f, 0.0f,
+    0.0f, 0.0f,
+
+    1.0f, 0.0f,  // -Y side
+    1.0f, 1.0f,
+    0.0f, 1.0f,
+    1.0f, 0.0f,
     0.0f, 1.0f,
     0.0f, 0.0f,
-    1.0f, 1.0f,
-    0.0f, 0.0f,
-    1.0f, 0.0f,
 
-    1.0f, 1.0f,  // +X side
+    1.0f, 0.0f,  // +Y side
+    0.0f, 0.0f,
     0.0f, 1.0f,
-    0.0f, 0.0f,
-    0.0f, 0.0f,
     1.0f, 0.0f,
+    0.0f, 1.0f,
     1.0f, 1.0f,
 
-    0.0f, 1.0f,  // +Z side
+    1.0f, 0.0f,  // +X side
     0.0f, 0.0f,
+    0.0f, 1.0f,
+    0.0f, 1.0f,
     1.0f, 1.0f,
-    0.0f, 0.0f,
     1.0f, 0.0f,
+
+    0.0f, 0.0f,  // +Z side
+    0.0f, 1.0f,
+    1.0f, 0.0f,
+    0.0f, 1.0f,
     1.0f, 1.0f,
+    1.0f, 0.0f,
 };
 // clang-format on
 
@@ -266,51 +259,6 @@
 }
 
 VKAPI_ATTR VkBool32 VKAPI_CALL
-dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
-        uint64_t srcObject, size_t location, int32_t msgCode,
-        const char *pLayerPrefix, const char *pMsg, void *pUserData) {
-    char *message = (char *)malloc(strlen(pMsg) + 100);
-
-    assert(message);
-
-    if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
-        sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode,
-                pMsg);
-        validation_error = 1;
-    } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
-        // We know that we're submitting queues without fences, ignore this
-        // warning
-        if (strstr(pMsg,
-                   "vkQueueSubmit parameter, VkFence fence, is null pointer")) {
-            return false;
-        }
-        sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode,
-                pMsg);
-        validation_error = 1;
-    } else {
-        validation_error = 1;
-        return false;
-    }
-
-#ifdef _WIN32
-    MessageBox(NULL, message, "Alert", MB_OK);
-#else
-    printf("%s\n", message);
-    fflush(stdout);
-#endif
-    free(message);
-
-    /*
-     * false indicates that layer should not bail-out of an
-     * API call that had validation failures. This may mean that the
-     * app dies inside the driver due to invalid parameter(s).
-     * That's what would happen without validation layers, so we'll
-     * keep that behavior here.
-     */
-    return false;
-}
-
-VKAPI_ATTR VkBool32 VKAPI_CALL
 BreakCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
               uint64_t srcObject, size_t location, int32_t msgCode,
               const char *pLayerPrefix, const char *pMsg,
@@ -336,6 +284,7 @@
     HINSTANCE connection;        // hInstance - Windows Instance
     char name[APP_NAME_STR_LEN]; // Name to put on the window/icon
     HWND window;                 // hWnd - window handle
+    POINT minsize;               // minimum window size
 #elif defined(VK_USE_PLATFORM_XLIB_KHR) | defined(VK_USE_PLATFORM_XCB_KHR)
     Display* display;
     Window xlib_window;
@@ -345,6 +294,13 @@
     xcb_screen_t *screen;
     xcb_window_t xcb_window;
     xcb_intern_atom_reply_t *atom_wm_delete_window;
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    struct wl_display *display;
+    struct wl_registry *registry;
+    struct wl_compositor *compositor;
+    struct wl_surface *window;
+    struct wl_shell *shell;
+    struct wl_shell_surface *shell_surface;
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
     ANativeWindow* window;
 #endif
@@ -356,8 +312,12 @@
     VkInstance inst;
     VkPhysicalDevice gpu;
     VkDevice device;
-    VkQueue queue;
-    uint32_t graphics_queue_node_index;
+    VkQueue graphics_queue;
+    VkQueue present_queue;
+    uint32_t graphics_queue_family_index;
+    uint32_t present_queue_family_index;
+    VkSemaphore image_acquired_semaphore;
+    VkSemaphore draw_complete_semaphore;
     VkPhysicalDeviceProperties gpu_props;
     VkQueueFamilyProperties *queue_props;
     VkPhysicalDeviceMemoryProperties memory_properties;
@@ -365,7 +325,7 @@
     uint32_t enabled_extension_count;
     uint32_t enabled_layer_count;
     char *extension_names[64];
-    char *device_validation_layers[64];
+    char *enabled_layers[64];
 
     int width, height;
     VkFormat format;
@@ -436,6 +396,7 @@
     int32_t frameCount;
     bool validate;
     bool use_break;
+    bool suppress_popups;
     PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback;
     PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback;
     VkDebugReportCallbackEXT msg_callback;
@@ -445,6 +406,53 @@
     uint32_t queue_count;
 };
 
+VKAPI_ATTR VkBool32 VKAPI_CALL
+dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
+    uint64_t srcObject, size_t location, int32_t msgCode,
+    const char *pLayerPrefix, const char *pMsg, void *pUserData) {
+    char *message = (char *)malloc(strlen(pMsg) + 100);
+
+    assert(message);
+
+    if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+        sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode,
+            pMsg);
+        validation_error = 1;
+    } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
+        // We know that we're submitting queues without fences, ignore this
+        // warning
+        if (strstr(pMsg,
+            "vkQueueSubmit parameter, VkFence fence, is null pointer")) {
+            return false;
+        }
+        sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode,
+            pMsg);
+        validation_error = 1;
+    } else {
+        validation_error = 1;
+        return false;
+    }
+
+#ifdef _WIN32
+    struct demo *demo = (struct demo*) pUserData;
+    if (!demo->suppress_popups)
+        MessageBox(NULL, message, "Alert", MB_OK);
+#else
+    printf("%s\n", message);
+    fflush(stdout);
+#endif
+    free(message);
+
+    /*
+    * false indicates that layer should not bail-out of an
+    * API call that had validation failures. This may mean that the
+    * app dies inside the driver due to invalid parameter(s).
+    * That's what would happen without validation layers, so we'll
+    * keep that behavior here.
+    */
+    return false;
+}
+
 // Forward declaration:
 static void demo_resize(struct demo *demo);
 
@@ -470,14 +478,20 @@
 static void demo_flush_init_cmd(struct demo *demo) {
     VkResult U_ASSERT_ONLY err;
 
+    // This function could get called twice if the texture uses a staging buffer
+    // In that case the second call should be ignored
     if (demo->cmd == VK_NULL_HANDLE)
         return;
 
     err = vkEndCommandBuffer(demo->cmd);
     assert(!err);
 
+    VkFence fence;
+    VkFenceCreateInfo fence_ci = {.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+                                  .pNext = NULL,
+                                  .flags = 0};
+    vkCreateFence(demo->device, &fence_ci, NULL, &fence);
     const VkCommandBuffer cmd_bufs[] = {demo->cmd};
-    VkFence nullFence = VK_NULL_HANDLE;
     VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
                                 .pNext = NULL,
                                 .waitSemaphoreCount = 0,
@@ -488,13 +502,14 @@
                                 .signalSemaphoreCount = 0,
                                 .pSignalSemaphores = NULL};
 
-    err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence);
+    err = vkQueueSubmit(demo->graphics_queue, 1, &submit_info, fence);
     assert(!err);
 
-    err = vkQueueWaitIdle(demo->queue);
+    err = vkWaitForFences(demo->device, 1, &fence, VK_TRUE, UINT64_MAX);
     assert(!err);
 
     vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, cmd_bufs);
+    vkDestroyFence(demo->device, fence, NULL);
     demo->cmd = VK_NULL_HANDLE;
 }
 
@@ -516,22 +531,11 @@
 
         err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->cmd);
         assert(!err);
-
-        VkCommandBufferInheritanceInfo cmd_buf_hinfo = {
-            .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
-            .pNext = NULL,
-            .renderPass = VK_NULL_HANDLE,
-            .subpass = 0,
-            .framebuffer = VK_NULL_HANDLE,
-            .occlusionQueryEnable = VK_FALSE,
-            .queryFlags = 0,
-            .pipelineStatistics = 0,
-        };
         VkCommandBufferBeginInfo cmd_buf_info = {
             .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
             .pNext = NULL,
             .flags = 0,
-            .pInheritanceInfo = &cmd_buf_hinfo,
+            .pInheritanceInfo = NULL,
         };
         err = vkBeginCommandBuffer(demo->cmd, &cmd_buf_info);
         assert(!err);
@@ -578,21 +582,11 @@
 }
 
 static void demo_draw_build_cmd(struct demo *demo, VkCommandBuffer cmd_buf) {
-    VkCommandBufferInheritanceInfo cmd_buf_hinfo = {
-        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
-        .pNext = NULL,
-        .renderPass = VK_NULL_HANDLE,
-        .subpass = 0,
-        .framebuffer = VK_NULL_HANDLE,
-        .occlusionQueryEnable = VK_FALSE,
-        .queryFlags = 0,
-        .pipelineStatistics = 0,
-    };
     const VkCommandBufferBeginInfo cmd_buf_info = {
         .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
         .pNext = NULL,
-        .flags = 0,
-        .pInheritanceInfo = &cmd_buf_hinfo,
+        .flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
+        .pInheritanceInfo = NULL,
     };
     const VkClearValue clear_values[2] = {
             [0] = {.color.float32 = {0.2f, 0.2f, 0.2f, 0.2f}},
@@ -629,9 +623,9 @@
         .image = demo->buffers[demo->current_buffer].image,
         .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
 
-    vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0,
-                         NULL, 1, &image_memory_barrier);
+    vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0,
+                         NULL, 0, NULL, 1, &image_memory_barrier);
 
     vkCmdBeginRenderPass(cmd_buf, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
 
@@ -655,25 +649,10 @@
     scissor.offset.y = 0;
     vkCmdSetScissor(cmd_buf, 0, 1, &scissor);
     vkCmdDraw(cmd_buf, 12 * 3, 1, 0, 0);
+    // Note that ending the renderpass changes the image's layout from
+    // COLOR_ATTACHEMENT_OPTIMAL to PRESENT_SRC_KHR
     vkCmdEndRenderPass(cmd_buf);
 
-    VkImageMemoryBarrier prePresentBarrier = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-        .pNext = NULL,
-        .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-        .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
-        .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-        .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
-
-    prePresentBarrier.image = demo->buffers[demo->current_buffer].image;
-    VkImageMemoryBarrier *pmemory_barrier = &prePresentBarrier;
-    vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0,
-                         NULL, 1, pmemory_barrier);
-
     err = vkEndCommandBuffer(cmd_buf);
     assert(!err);
 }
@@ -704,29 +683,16 @@
 
 static void demo_draw(struct demo *demo) {
     VkResult U_ASSERT_ONLY err;
-    VkSemaphore presentCompleteSemaphore;
-    VkSemaphoreCreateInfo presentCompleteSemaphoreCreateInfo = {
-        .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
-        .pNext = NULL,
-        .flags = 0,
-    };
-    VkFence nullFence = VK_NULL_HANDLE;
-
-    err = vkCreateSemaphore(demo->device, &presentCompleteSemaphoreCreateInfo,
-                            NULL, &presentCompleteSemaphore);
-    assert(!err);
 
     // Get the index of the next available swapchain image:
     err = demo->fpAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX,
-                                      presentCompleteSemaphore,
-                                      (VkFence)0, // TODO: Show use of fence
+                                      demo->image_acquired_semaphore, (VkFence)0,
                                       &demo->current_buffer);
     if (err == VK_ERROR_OUT_OF_DATE_KHR) {
         // demo->swapchain is out of date (e.g. the window was resized) and
         // must be recreated:
         demo_resize(demo);
         demo_draw(demo);
-        vkDestroySemaphore(demo->device, presentCompleteSemaphore, NULL);
         return;
     } else if (err == VK_SUBOPTIMAL_KHR) {
         // demo->swapchain is not as optimal as it could be, but the platform's
@@ -735,27 +701,25 @@
         assert(!err);
     }
 
-    demo_flush_init_cmd(demo);
-
-    // Wait for the present complete semaphore to be signaled to ensure
+    // Wait for the image acquired semaphore to be signaled to ensure
     // that the image won't be rendered to until the presentation
     // engine has fully released ownership to the application, and it is
     // okay to render to the image.
-
+    VkFence nullFence = VK_NULL_HANDLE;
     VkPipelineStageFlags pipe_stage_flags =
-        VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
-    VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
-                                .pNext = NULL,
-                                .waitSemaphoreCount = 1,
-                                .pWaitSemaphores = &presentCompleteSemaphore,
-                                .pWaitDstStageMask = &pipe_stage_flags,
-                                .commandBufferCount = 1,
-                                .pCommandBuffers =
-                                    &demo->buffers[demo->current_buffer].cmd,
-                                .signalSemaphoreCount = 0,
-                                .pSignalSemaphores = NULL};
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    VkSubmitInfo submit_info = {
+        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+        .pNext = NULL,
+        .waitSemaphoreCount = 1,
+        .pWaitSemaphores = &demo->image_acquired_semaphore,
+        .pWaitDstStageMask = &pipe_stage_flags,
+        .commandBufferCount = 1,
+        .pCommandBuffers = &demo->buffers[demo->current_buffer].cmd,
+        .signalSemaphoreCount = 1,
+        .pSignalSemaphores = &demo->draw_complete_semaphore};
 
-    err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence);
+    err = vkQueueSubmit(demo->graphics_queue, 1, &submit_info, nullFence);
     assert(!err);
 
     VkPresentInfoKHR present = {
@@ -764,10 +728,12 @@
         .swapchainCount = 1,
         .pSwapchains = &demo->swapchain,
         .pImageIndices = &demo->current_buffer,
+        .waitSemaphoreCount = 1,
+        .pWaitSemaphores = &demo->draw_complete_semaphore,
     };
 
     // TBD/TODO: SHOULD THE "present" PARAMETER BE "const" IN THE HEADER?
-    err = demo->fpQueuePresentKHR(demo->queue, &present);
+    err = demo->fpQueuePresentKHR(demo->present_queue, &present);
     if (err == VK_ERROR_OUT_OF_DATE_KHR) {
         // demo->swapchain is out of date (e.g. the window was resized) and
         // must be recreated:
@@ -778,11 +744,6 @@
     } else {
         assert(!err);
     }
-
-    err = vkQueueWaitIdle(demo->queue);
-    assert(err == VK_SUCCESS);
-
-    vkDestroySemaphore(demo->device, presentCompleteSemaphore, NULL);
 }
 
 static void demo_prepare_buffers(struct demo *demo) {
@@ -841,6 +802,8 @@
     // queued for display):
     uint32_t desiredNumberOfSwapchainImages =
         surfCapabilities.minImageCount + 1;
+    // If maxImageCount is 0, we can ask for as many images as we want, otherwise
+    // we're limited to maxImageCount
     if ((surfCapabilities.maxImageCount > 0) &&
         (desiredNumberOfSwapchainImages > surfCapabilities.maxImageCount)) {
         // Application must settle for fewer images than desired:
@@ -855,7 +818,7 @@
         preTransform = surfCapabilities.currentTransform;
     }
 
-    const VkSwapchainCreateInfoKHR swapchain = {
+    VkSwapchainCreateInfoKHR swapchain_ci = {
         .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
         .pNext = NULL,
         .surface = demo->surface,
@@ -878,8 +841,18 @@
         .clipped = true,
     };
     uint32_t i;
+    uint32_t queueFamilyIndices[2] = {(uint32_t) demo->graphics_queue_family_index, (uint32_t) demo->present_queue_family_index};
+    if (demo->graphics_queue_family_index != demo->present_queue_family_index)
+    {
+        // If the graphics and present queues are from different queue families, we either have to
+        // explicitly transfer ownership of images between the queues, or we have to create the swapchain
+        // with imageSharingMode as VK_SHARING_MODE_CONCURRENT
+        swapchain_ci.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
+        swapchain_ci.queueFamilyIndexCount = 2;
+        swapchain_ci.pQueueFamilyIndices = queueFamilyIndices;
+    }
 
-    err = demo->fpCreateSwapchainKHR(demo->device, &swapchain, NULL,
+    err = demo->fpCreateSwapchainKHR(demo->device, &swapchain_ci, NULL,
                                      &demo->swapchain);
     assert(!err);
 
@@ -1028,7 +1001,7 @@
         return false;
     }
     while(strncmp(cPtr++, "\n", 1));
-    sscanf(cPtr, "%u %u", height, width);
+    sscanf(cPtr, "%u %u", width, height);
     if (rgba_data == NULL) {
         return true;
     }
@@ -1071,7 +1044,7 @@
         }
     } while (!strncmp(header, "#", 1));
 
-    sscanf(header, "%u %u", height, width);
+    sscanf(header, "%u %u", width, height);
     if (rgba_data == NULL) {
         fclose(fPtr);
         return true;
@@ -1442,7 +1415,7 @@
                  .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                  .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
                  .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                 .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                 .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
                 },
             [1] =
                 {
@@ -1808,7 +1781,7 @@
     const VkCommandPoolCreateInfo cmd_pool_info = {
         .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
         .pNext = NULL,
-        .queueFamilyIndex = demo->graphics_queue_node_index,
+        .queueFamilyIndex = demo->graphics_queue_family_index,
         .flags = 0,
     };
     err = vkCreateCommandPool(demo->device, &cmd_pool_info, NULL,
@@ -1862,6 +1835,7 @@
     uint32_t i;
 
     demo->prepared = false;
+    vkDeviceWaitIdle(demo->device);
 
     for (i = 0; i < demo->swapchainImageCount; i++) {
         vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL);
@@ -1900,6 +1874,8 @@
     free(demo->queue_props);
 
     vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL);
+    vkDestroySemaphore(demo->device, demo->image_acquired_semaphore, NULL);
+    vkDestroySemaphore(demo->device, demo->draw_complete_semaphore, NULL);
     vkDestroyDevice(demo->device, NULL);
     if (demo->validate) {
         demo->DestroyDebugReportCallback(demo->inst, demo->msg_callback, NULL);
@@ -1920,6 +1896,13 @@
     xcb_destroy_window(demo->connection, demo->xcb_window);
     xcb_disconnect(demo->connection);
     free(demo->atom_wm_delete_window);
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    wl_shell_surface_destroy(demo->shell_surface);
+    wl_surface_destroy(demo->window);
+    wl_shell_destroy(demo->shell);
+    wl_compositor_destroy(demo->compositor);
+    wl_registry_destroy(demo->registry);
+    wl_display_disconnect(demo->display);
 #endif
 }
 
@@ -1935,6 +1918,7 @@
     //
     // First, perform part of the demo_cleanup() function:
     demo->prepared = false;
+    vkDeviceWaitIdle(demo->device);
 
     for (i = 0; i < demo->swapchainImageCount; i++) {
         vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL);
@@ -1982,15 +1966,9 @@
 static void demo_run(struct demo *demo) {
     if (!demo->prepared)
         return;
-    // Wait for work to finish before updating MVP.
-    vkDeviceWaitIdle(demo->device);
+
     demo_update_data_buffer(demo);
-
     demo_draw(demo);
-
-    // Wait for work to finish before updating MVP.
-    vkDeviceWaitIdle(demo->device);
-
     demo->curFrame++;
     if (demo->frameCount != INT_MAX && demo->curFrame == demo->frameCount) {
         PostQuitMessage(validation_error);
@@ -2006,13 +1984,16 @@
     case WM_PAINT:
         demo_run(&demo);
         break;
+    case WM_GETMINMAXINFO:     // set window's minimum size
+        ((MINMAXINFO*)lParam)->ptMinTrackSize = demo.minsize;
+        return 0;
     case WM_SIZE:
         // Resize the application to the new window size, except when
         // it was minimized. Vulkan doesn't support images or swapchains
         // with width=0 and height=0.
         if (wParam != SIZE_MINIMIZED) {
             demo.width = lParam & 0xffff;
-            demo.height = lParam & 0xffff0000 >> 16;
+            demo.height = (lParam & 0xffff0000) >> 16;
             demo_resize(&demo);
         }
         break;
@@ -2066,14 +2047,17 @@
         fflush(stdout);
         exit(1);
     }
+    // Window client area size must be at least 1 pixel high, to prevent crash.
+    demo->minsize.x = GetSystemMetrics(SM_CXMINTRACK);
+    demo->minsize.y = GetSystemMetrics(SM_CYMINTRACK)+1;
 }
-#elif defined(VK_USE_PLATFORM_XLIB_KHR) | defined(VK_USE_PLATFORM_XCB_KHR)
+#elif defined(VK_USE_PLATFORM_XLIB_KHR)
 static void demo_create_xlib_window(struct demo *demo) {
 
     demo->display = XOpenDisplay(NULL);
     long visualMask = VisualScreenMask;
     int numberOfVisuals;
-    XVisualInfo vInfoTemplate;
+    XVisualInfo vInfoTemplate={};
     vInfoTemplate.screen = DefaultScreen(demo->display);
     XVisualInfo *visualInfo = XGetVisualInfo(demo->display, visualMask,
                                              &vInfoTemplate, &numberOfVisuals);
@@ -2082,7 +2066,7 @@
                 demo->display, RootWindow(demo->display, vInfoTemplate.screen),
                 visualInfo->visual, AllocNone);
 
-    XSetWindowAttributes windowAttributes;
+    XSetWindowAttributes windowAttributes={};
     windowAttributes.colormap = colormap;
     windowAttributes.background_pixel = 0xFFFFFFFF;
     windowAttributes.border_pixel = 0;
@@ -2152,20 +2136,15 @@
             }
         }
 
-        // Wait for work to finish before updating MVP.
-        vkDeviceWaitIdle(demo->device);
         demo_update_data_buffer(demo);
-
         demo_draw(demo);
-
-        // Wait for work to finish before updating MVP.
-        vkDeviceWaitIdle(demo->device);
         demo->curFrame++;
         if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount)
             demo->quit = true;
     }
 }
-
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
 static void demo_handle_xcb_event(struct demo *demo,
                               const xcb_generic_event_t *event) {
     uint8_t event_code = event->response_type & 0x7f;
@@ -2222,20 +2201,15 @@
             event = xcb_wait_for_event(demo->connection);
         } else {
             event = xcb_poll_for_event(demo->connection);
-        }
-        if (event) {
-            demo_handle_xcb_event(demo, event);
-            free(event);
+            while(event) {
+                demo_handle_xcb_event(demo, event);
+                free(event);
+                event = xcb_poll_for_event(demo->connection);
+            }
         }
 
-        // Wait for work to finish before updating MVP.
-        vkDeviceWaitIdle(demo->device);
         demo_update_data_buffer(demo);
-
         demo_draw(demo);
-
-        // Wait for work to finish before updating MVP.
-        vkDeviceWaitIdle(demo->device);
         demo->curFrame++;
         if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount)
             demo->quit = true;
@@ -2281,20 +2255,61 @@
     xcb_configure_window(demo->connection, demo->xcb_window,
                          XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
 }
+#endif // VK_USE_PLATFORM_XCB_KHR
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+static void demo_run(struct demo *demo) {
+    while (!demo->quit) {
+        demo_update_data_buffer(demo);
+        demo_draw(demo);
+        demo->curFrame++;
+        if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount)
+            demo->quit = true;
+    }
+}
+
+static void handle_ping(void *data UNUSED,
+                        struct wl_shell_surface *shell_surface,
+                        uint32_t serial) {
+    wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void handle_configure(void *data UNUSED,
+                             struct wl_shell_surface *shell_surface UNUSED,
+                             uint32_t edges UNUSED, int32_t width UNUSED,
+                             int32_t height UNUSED) {}
+
+static void handle_popup_done(void *data UNUSED,
+                              struct wl_shell_surface *shell_surface UNUSED) {}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+    handle_ping, handle_configure, handle_popup_done};
+
+static void demo_create_window(struct demo *demo) {
+    demo->window = wl_compositor_create_surface(demo->compositor);
+    if (!demo->window) {
+        printf("Can not create wayland_surface from compositor!\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    demo->shell_surface = wl_shell_get_shell_surface(demo->shell, demo->window);
+    if (!demo->shell_surface) {
+        printf("Can not get shell_surface from wayland_surface!\n");
+        fflush(stdout);
+        exit(1);
+    }
+    wl_shell_surface_add_listener(demo->shell_surface, &shell_surface_listener,
+                                  demo);
+    wl_shell_surface_set_toplevel(demo->shell_surface);
+    wl_shell_surface_set_title(demo->shell_surface, APP_SHORT_NAME);
+}
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
 static void demo_run(struct demo *demo) {
     if (!demo->prepared)
         return;
 
-    // Wait for work to finish before updating MVP.
-    vkDeviceWaitIdle(demo->device);
     demo_update_data_buffer(demo);
-
     demo_draw(demo);
-
-    // Wait for work to finish before updating MVP.
-    vkDeviceWaitIdle(demo->device);
-
     demo->curFrame++;
 }
 #endif
@@ -2326,7 +2341,7 @@
     VkResult err;
     uint32_t instance_extension_count = 0;
     uint32_t instance_layer_count = 0;
-    uint32_t device_validation_layer_count = 0;
+    uint32_t validation_layer_count = 0;
     char **instance_validation_layers = NULL;
     demo->enabled_extension_count = 0;
     demo->enabled_layer_count = 0;
@@ -2336,10 +2351,10 @@
     };
 
     char *instance_validation_layers_alt2[] = {
-        "VK_LAYER_GOOGLE_threading",     "VK_LAYER_LUNARG_parameter_validation",
-        "VK_LAYER_LUNARG_device_limits", "VK_LAYER_LUNARG_object_tracker",
-        "VK_LAYER_LUNARG_image",         "VK_LAYER_LUNARG_core_validation",
-        "VK_LAYER_LUNARG_swapchain",     "VK_LAYER_GOOGLE_unique_objects"
+        "VK_LAYER_GOOGLE_threading",       "VK_LAYER_LUNARG_parameter_validation",
+        "VK_LAYER_LUNARG_object_tracker",  "VK_LAYER_LUNARG_image",
+        "VK_LAYER_LUNARG_core_validation", "VK_LAYER_LUNARG_swapchain",
+        "VK_LAYER_GOOGLE_unique_objects"
     };
 
     /* Look for validation layers */
@@ -2364,8 +2379,8 @@
                     instance_layers);
             if (validation_found) {
                 demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
-                demo->device_validation_layers[0] = "VK_LAYER_LUNARG_standard_validation";
-                device_validation_layer_count = 1;
+                demo->enabled_layers[0] = "VK_LAYER_LUNARG_standard_validation";
+                validation_layer_count = 1;
             } else {
                 // use alternative set of validation layers
                 instance_validation_layers = instance_validation_layers_alt2;
@@ -2374,11 +2389,10 @@
                     ARRAY_SIZE(instance_validation_layers_alt2),
                     instance_validation_layers, instance_layer_count,
                     instance_layers);
-                device_validation_layer_count =
-                        ARRAY_SIZE(instance_validation_layers_alt2);
-                for (uint32_t i = 0; i < device_validation_layer_count; i++) {
-                    demo->device_validation_layers[i] =
-                            instance_validation_layers[i];
+                validation_layer_count =
+                    ARRAY_SIZE(instance_validation_layers_alt2);
+                for (uint32_t i = 0; i < validation_layer_count; i++) {
+                    demo->enabled_layers[i] = instance_validation_layers[i];
                 }
             }
             free(instance_layers);
@@ -2443,6 +2457,14 @@
                     VK_KHR_XCB_SURFACE_EXTENSION_NAME;
             }
 #endif
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+            if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
+                        instance_extensions[i].extensionName)) {
+                platformSurfaceExtFound = 1;
+                demo->extension_names[demo->enabled_extension_count++] =
+                    VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
+            }
+#endif
 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
             if (!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
                         instance_extensions[i].extensionName)) {
@@ -2490,6 +2512,14 @@
                  "look at the Getting Started guide for additional "
                  "information.\n",
                  "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+                 "the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+                 " extension.\n\nDo you have a compatible "
+                 "Vulkan installable client driver (ICD) installed?\nPlease "
+                 "look at the Getting Started guide for additional "
+                 "information.\n",
+                 "vkCreateInstance Failure");
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
         ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
                  "the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
@@ -2540,7 +2570,7 @@
         dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
         dbgCreateInfo.pNext = NULL;
         dbgCreateInfo.pfnCallback = demo->use_break ? BreakCallback : dbgFunc;
-        dbgCreateInfo.pUserData = NULL;
+        dbgCreateInfo.pUserData = demo;
         dbgCreateInfo.flags =
             VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
         inst_info.pNext = &dbgCreateInfo;
@@ -2584,40 +2614,6 @@
                  "vkEnumeratePhysicalDevices Failure");
     }
 
-    /* Look for validation layers */
-    validation_found = 0;
-    demo->enabled_layer_count = 0;
-    uint32_t device_layer_count = 0;
-    err =
-        vkEnumerateDeviceLayerProperties(demo->gpu, &device_layer_count, NULL);
-    assert(!err);
-
-    if (device_layer_count > 0) {
-        VkLayerProperties *device_layers =
-            malloc(sizeof(VkLayerProperties) * device_layer_count);
-        err = vkEnumerateDeviceLayerProperties(demo->gpu, &device_layer_count,
-                                               device_layers);
-        assert(!err);
-
-        if (demo->validate) {
-            validation_found = demo_check_layers(device_validation_layer_count,
-                                                 demo->device_validation_layers,
-                                                 device_layer_count,
-                                                 device_layers);
-            demo->enabled_layer_count = device_validation_layer_count;
-        }
-
-        free(device_layers);
-    }
-
-    if (demo->validate && !validation_found) {
-        ERR_EXIT("vkEnumerateDeviceLayerProperties failed to find "
-                 "a required validation layer.\n\n"
-                 "Please look at the Getting Started guide for additional "
-                 "information.\n",
-                 "vkCreateDevice Failure");
-    }
-
     /* Look for device extensions */
     uint32_t device_extension_count = 0;
     VkBool32 swapchainExtFound = 0;
@@ -2689,7 +2685,7 @@
         dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
         dbgCreateInfo.pNext = NULL;
         dbgCreateInfo.pfnCallback = callback;
-        dbgCreateInfo.pUserData = NULL;
+        dbgCreateInfo.pUserData = demo;
         dbgCreateInfo.flags =
             VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
         err = demo->CreateDebugReportCallback(demo->inst, &dbgCreateInfo, NULL,
@@ -2745,7 +2741,7 @@
     const VkDeviceQueueCreateInfo queue = {
         .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
         .pNext = NULL,
-        .queueFamilyIndex = demo->graphics_queue_node_index,
+        .queueFamilyIndex = demo->graphics_queue_family_index,
         .queueCount = 1,
         .pQueuePriorities = queue_priorities};
 
@@ -2754,11 +2750,8 @@
         .pNext = NULL,
         .queueCreateInfoCount = 1,
         .pQueueCreateInfos = &queue,
-        .enabledLayerCount = demo->enabled_layer_count,
-        .ppEnabledLayerNames =
-            (const char *const *)((demo->validate)
-                                      ? demo->device_validation_layers
-                                      : NULL),
+        .enabledLayerCount = 0,
+        .ppEnabledLayerNames = NULL,
         .enabledExtensionCount = demo->enabled_extension_count,
         .ppEnabledExtensionNames = (const char *const *)demo->extension_names,
         .pEnabledFeatures =
@@ -2784,6 +2777,16 @@
 
     err =
         vkCreateWin32SurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) && !defined(VK_USE_PLATFORM_XCB_KHR)
+    VkWaylandSurfaceCreateInfoKHR createInfo;
+    createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
+    createInfo.pNext = NULL;
+    createInfo.flags = 0;
+    createInfo.display = demo->display;
+    createInfo.surface = demo->window;
+
+    err = vkCreateWaylandSurfaceKHR(demo->inst, &createInfo, NULL,
+                                    &demo->surface);
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
     VkAndroidSurfaceCreateInfoKHR createInfo;
     createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
@@ -2833,48 +2836,25 @@
     uint32_t graphicsQueueNodeIndex = UINT32_MAX;
     uint32_t presentQueueNodeIndex = UINT32_MAX;
     for (i = 0; i < demo->queue_count; i++) {
-        if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
-            if (graphicsQueueNodeIndex == UINT32_MAX) {
-                graphicsQueueNodeIndex = i;
-            }
+        if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0
+                && graphicsQueueNodeIndex == UINT32_MAX) {
+            graphicsQueueNodeIndex = i;
+        }
 
-            if (supportsPresent[i] == VK_TRUE) {
-                graphicsQueueNodeIndex = i;
-                presentQueueNodeIndex = i;
-                break;
-            }
+        if (supportsPresent[i] == VK_TRUE && presentQueueNodeIndex == UINT32_MAX) {
+            presentQueueNodeIndex = i;
         }
     }
-    if (presentQueueNodeIndex == UINT32_MAX) {
-        // If didn't find a queue that supports both graphics and present, then
-        // find a separate present queue.
-        for (uint32_t i = 0; i < demo->queue_count; ++i) {
-            if (supportsPresent[i] == VK_TRUE) {
-                presentQueueNodeIndex = i;
-                break;
-            }
-        }
-    }
-    free(supportsPresent);
 
     // Generate error if could not find both a graphics and a present queue
     if (graphicsQueueNodeIndex == UINT32_MAX ||
         presentQueueNodeIndex == UINT32_MAX) {
-        ERR_EXIT("Could not find a graphics and a present queue\n",
+        ERR_EXIT("Could not find both graphics and present queues\n",
                  "Swapchain Initialization Failure");
     }
 
-    // TODO: Add support for separate queues, including presentation,
-    //       synchronization, and appropriate tracking for QueueSubmit.
-    // NOTE: While it is possible for an application to use a separate graphics
-    //       and a present queues, this demo program assumes it is only using
-    //       one:
-    if (graphicsQueueNodeIndex != presentQueueNodeIndex) {
-        ERR_EXIT("Could not find a common graphics and a present queue\n",
-                 "Swapchain Initialization Failure");
-    }
-
-    demo->graphics_queue_node_index = graphicsQueueNodeIndex;
+    demo->graphics_queue_family_index = graphicsQueueNodeIndex;
+    demo->present_queue_family_index = presentQueueNodeIndex;
 
     demo_create_device(demo);
 
@@ -2884,8 +2864,15 @@
     GET_DEVICE_PROC_ADDR(demo->device, AcquireNextImageKHR);
     GET_DEVICE_PROC_ADDR(demo->device, QueuePresentKHR);
 
-    vkGetDeviceQueue(demo->device, demo->graphics_queue_node_index, 0,
-                     &demo->queue);
+    vkGetDeviceQueue(demo->device, demo->graphics_queue_family_index, 0,
+                     &demo->graphics_queue);
+
+    if (demo->graphics_queue_family_index == demo->present_queue_family_index) {
+        demo->present_queue = demo->graphics_queue;
+    } else {
+        vkGetDeviceQueue(demo->device, demo->present_queue_family_index, 0,
+                         &demo->present_queue);
+    }
 
     // Get the list of VkFormat's that are supported:
     uint32_t formatCount;
@@ -2911,10 +2898,48 @@
     demo->quit = false;
     demo->curFrame = 0;
 
+    // Create semaphores to synchronize acquiring presentable buffers before
+    // rendering and waiting for drawing to be complete before presenting
+    VkSemaphoreCreateInfo semaphoreCreateInfo = {
+        .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+        .pNext = NULL,
+        .flags = 0,
+    };
+    err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL,
+                            &demo->image_acquired_semaphore);
+    assert(!err);
+
+    err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL,
+                            &demo->draw_complete_semaphore);
+    assert(!err);
+
     // Get Memory information and properties
     vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties);
 }
 
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) && !defined(VK_USE_PLATFORM_XCB_KHR)
+static void registry_handle_global(void *data, struct wl_registry *registry,
+                                   uint32_t name, const char *interface,
+                                   uint32_t version UNUSED) {
+    struct demo *demo = data;
+    if (strcmp(interface, "wl_compositor") == 0) {
+        demo->compositor =
+            wl_registry_bind(registry, name, &wl_compositor_interface, 3);
+        /* Todo: When xdg_shell protocol has stablized, we should move wl_shell
+         * tp xdg_shell */
+    } else if (strcmp(interface, "wl_shell") == 0) {
+        demo->shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
+    }
+}
+
+static void registry_handle_global_remove(void *data UNUSED,
+                                          struct wl_registry *registry UNUSED,
+                                          uint32_t name UNUSED) {}
+
+static const struct wl_registry_listener registry_listener = {
+    registry_handle_global, registry_handle_global_remove};
+#endif
+
 static void demo_init_connection(struct demo *demo) {
 #if defined(VK_USE_PLATFORM_XCB_KHR)
     const xcb_setup_t *setup;
@@ -2922,7 +2947,7 @@
     int scr;
 
     demo->connection = xcb_connect(NULL, &scr);
-    if (demo->connection == NULL) {
+    if (xcb_connection_has_error(demo->connection) > 0) {
         printf("Cannot find a compatible Vulkan installable client driver "
                "(ICD).\nExiting ...\n");
         fflush(stdout);
@@ -2935,6 +2960,19 @@
         xcb_screen_next(&iter);
 
     demo->screen = iter.data;
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    demo->display = wl_display_connect(NULL);
+
+    if (demo->display == NULL) {
+        printf("Cannot find a compatible Vulkan installable client driver "
+               "(ICD).\nExiting ...\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    demo->registry = wl_display_get_registry(demo->display);
+    wl_registry_add_listener(demo->registry, &registry_listener, demo);
+    wl_display_dispatch(demo->display);
 #endif
 }
 
@@ -2959,19 +2997,28 @@
             demo->validate = true;
             continue;
         }
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
         if (strcmp(argv[i], "--xlib") == 0) {
             demo->use_xlib = true;
             continue;
         }
+#endif
         if (strcmp(argv[i], "--c") == 0 && demo->frameCount == INT32_MAX &&
             i < argc - 1 && sscanf(argv[i + 1], "%d", &demo->frameCount) == 1 &&
             demo->frameCount >= 0) {
             i++;
             continue;
         }
+        if (strcmp(argv[i], "--suppress_popups") == 0) {
+            demo->suppress_popups = true;
+            continue;
+        }
 
         fprintf(stderr, "Usage:\n  %s [--use_staging] [--validate] [--break] "
-                        "[--c <framecount>]\n",
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+                        "[--xlib] "
+#endif
+                        "[--c <framecount>] [--suppress_popups]\n",
                 APP_SHORT_NAME);
         fflush(stderr);
         exit(1);
@@ -3162,19 +3209,35 @@
     struct demo demo;
 
     demo_init(&demo, argc, argv);
+#if defined(VK_USE_PLATFORM_XLIB_KHR) && defined(VK_USE_PLATFORM_XCB_KHR)
     if (demo.use_xlib)
         demo_create_xlib_window(&demo);
     else
         demo_create_xcb_window(&demo);
+#elif defined(VK_USE_PLATFORM_XCB_KHR)
+    demo_create_xcb_window(&demo);
+#elif defined(VK_USE_PLATFORM_XLIB_KHR)
+    demo_create_xlib_window(&demo);
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    demo_create_window(&demo);
+#endif
 
     demo_init_vk_swapchain(&demo);
 
     demo_prepare(&demo);
 
+#if defined(VK_USE_PLATFORM_XLIB_KHR) && defined(VK_USE_PLATFORM_XCB_KHR)
     if (demo.use_xlib)
         demo_run_xlib(&demo);
     else
         demo_run_xcb(&demo);
+#elif defined(VK_USE_PLATFORM_XCB_KHR)
+    demo_run_xcb(&demo);
+#elif defined(VK_USE_PLATFORM_XLIB_KHR)
+    demo_run_xlib(&demo);
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    demo_run(&demo);
+#endif
 
     demo_cleanup(&demo);
 
diff --git a/demos/lunarg.ppm b/demos/lunarg.ppm
index 87808e1..468b487 100644
--- a/demos/lunarg.ppm
+++ b/demos/lunarg.ppm
Binary files differ
diff --git a/demos/smoke/CMakeLists.txt b/demos/smoke/CMakeLists.txt
index a1789e9..4dc90cd 100644
--- a/demos/smoke/CMakeLists.txt
+++ b/demos/smoke/CMakeLists.txt
@@ -60,14 +60,23 @@
 
     list(APPEND sources ShellWin32.cpp ShellWin32.h)
 else()
-    list(APPEND libraries PRIVATE -ldl)
+    list(APPEND libraries PRIVATE -ldl -lrt)
 
-    find_package(XCB REQUIRED)
+    if(BUILD_WSI_XCB_SUPPORT)
+        find_package(XCB REQUIRED)
 
-    list(APPEND sources ShellXcb.cpp ShellXcb.h)
-    list(APPEND definitions PRIVATE -DVK_USE_PLATFORM_XCB_KHR)
-    list(APPEND includes PRIVATE ${XCB_INCLUDES})
-    list(APPEND libraries PRIVATE ${XCB_LIBRARIES})
+        list(APPEND sources ShellXcb.cpp ShellXcb.h)
+        list(APPEND definitions PRIVATE -DVK_USE_PLATFORM_XCB_KHR)
+        list(APPEND includes PRIVATE ${XCB_INCLUDES})
+        list(APPEND libraries PRIVATE ${XCB_LIBRARIES})
+    elseif(BUILD_WSI_WAYLAND_SUPPORT)
+        find_package(Wayland REQUIRED)
+
+        list(APPEND sources ShellWayland.cpp ShellWayland.h)
+        list(APPEND definitions PRIVATE -DVK_USE_PLATFORM_WAYLAND_KHR)
+        list(APPEND includes PRIVATE ${WAYLAND_CLIENT_INCLUDE_DIR})
+        list(APPEND libraries PRIVATE ${WAYLAND_CLIENT_LIBRARIES})
+    endif()
 endif()
 
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/demos)
diff --git a/demos/smoke/Helpers.h b/demos/smoke/Helpers.h
index e8cf2e8..532da7a 100644
--- a/demos/smoke/Helpers.h
+++ b/demos/smoke/Helpers.h
@@ -73,15 +73,6 @@
     return vk::EnumerateInstanceLayerProperties(&count, layer_props.data());
 }
 
-inline VkResult enumerate(VkPhysicalDevice phy, std::vector<VkLayerProperties> &layer_props)
-{
-    uint32_t count = 0;
-    vk::EnumerateDeviceLayerProperties(phy, &count, nullptr);
-
-    layer_props.resize(count);
-    return vk::EnumerateDeviceLayerProperties(phy, &count, layer_props.data());
-}
-
 inline VkResult get(VkPhysicalDevice phy, std::vector<VkQueueFamilyProperties> &queues)
 {
     uint32_t count = 0;
diff --git a/demos/smoke/Main.cpp b/demos/smoke/Main.cpp
index 7118c8e..a59ff1b 100644
--- a/demos/smoke/Main.cpp
+++ b/demos/smoke/Main.cpp
@@ -45,6 +45,21 @@
     return 0;
 }
 
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+
+#include "ShellWayland.h"
+
+int main(int argc, char **argv) {
+    Game *game = create_game(argc, argv);
+    {
+        ShellWayland shell(*game);
+        shell.run();
+    }
+    delete game;
+
+    return 0;
+}
+
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
 
 #include <android/log.h>
diff --git a/demos/smoke/Shell.cpp b/demos/smoke/Shell.cpp
index 084fa3f..5a08852 100644
--- a/demos/smoke/Shell.cpp
+++ b/demos/smoke/Shell.cpp
@@ -34,9 +34,7 @@
 
     // require "standard" validation layers
     if (settings_.validate) {
-        device_layers_.push_back("VK_LAYER_LUNARG_standard_validation");
         instance_layers_.push_back("VK_LAYER_LUNARG_standard_validation");
-
         instance_extensions_.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
     }
 }
@@ -132,25 +130,6 @@
     }
 }
 
-bool Shell::has_all_device_layers(VkPhysicalDevice phy) const
-{
-    // enumerate device layers
-    std::vector<VkLayerProperties> layers;
-    vk::enumerate(phy, layers);
-
-    std::set<std::string> layer_names;
-    for (const auto &layer : layers)
-        layer_names.insert(layer.layerName);
-
-    // all listed device layers are required
-    for (const auto &name : device_layers_) {
-        if (layer_names.find(name) == layer_names.end())
-            return false;
-    }
-
-    return true;
-}
-
 bool Shell::has_all_device_extensions(VkPhysicalDevice phy) const
 {
     // enumerate device extensions
@@ -223,7 +202,7 @@
 
     ctx_.physical_dev = VK_NULL_HANDLE;
     for (auto phy : phys) {
-        if (!has_all_device_layers(phy) || !has_all_device_extensions(phy))
+        if (!has_all_device_extensions(phy))
             continue;
 
         // get queue properties
@@ -321,8 +300,6 @@
 
     dev_info.pQueueCreateInfos = queue_info.data();
 
-    dev_info.enabledLayerCount = static_cast<uint32_t>(device_layers_.size());
-    dev_info.ppEnabledLayerNames = device_layers_.data();
     dev_info.enabledExtensionCount = static_cast<uint32_t>(device_extensions_.size());
     dev_info.ppEnabledExtensionNames = device_extensions_.data();
 
diff --git a/demos/smoke/Shell.h b/demos/smoke/Shell.h
index adabd57..31c4a2d 100644
--- a/demos/smoke/Shell.h
+++ b/demos/smoke/Shell.h
@@ -99,7 +99,6 @@
     std::vector<const char *> instance_layers_;
     std::vector<const char *> instance_extensions_;
 
-    std::vector<const char *> device_layers_;
     std::vector<const char *> device_extensions_;
 
 private:
diff --git a/demos/smoke/ShellWayland.cpp b/demos/smoke/ShellWayland.cpp
new file mode 100644
index 0000000..0d4bcbc
--- /dev/null
+++ b/demos/smoke/ShellWayland.cpp
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * Licensed under the Apache 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#include <cassert>
+#include <dlfcn.h>
+#include <sstream>
+#include <time.h>
+
+#include "Game.h"
+#include "Helpers.h"
+#include "ShellWayland.h"
+#include <stdio.h>
+#include <string.h>
+
+/* Unused attribute / variable MACRO.
+   Some methods of classes' heirs do not need all fuction parameters.
+   This triggers warning on GCC platfoms. This macro will silence them.
+*/
+#if defined(__GNUC__)
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
+
+namespace {
+
+class PosixTimer {
+  public:
+    PosixTimer() { reset(); }
+
+    void reset() { clock_gettime(CLOCK_MONOTONIC, &start_); }
+
+    double get() const {
+        struct timespec now;
+        clock_gettime(CLOCK_MONOTONIC, &now);
+
+        constexpr long one_s_in_ns = 1000 * 1000 * 1000;
+        constexpr double one_s_in_ns_d = static_cast<double>(one_s_in_ns);
+
+        time_t s = now.tv_sec - start_.tv_sec;
+        long ns;
+        if (now.tv_nsec > start_.tv_nsec) {
+            ns = now.tv_nsec - start_.tv_nsec;
+        } else {
+            assert(s > 0);
+            s--;
+            ns = one_s_in_ns - (start_.tv_nsec - now.tv_nsec);
+        }
+
+        return static_cast<double>(s) + static_cast<double>(ns) / one_s_in_ns_d;
+    }
+
+  private:
+    struct timespec start_;
+};
+
+} // namespace
+
+const struct wl_registry_listener ShellWayland::registry_listener_ = {
+    ShellWayland::handle_global, ShellWayland::handle_global_remove};
+
+const struct wl_shell_surface_listener ShellWayland::shell_surface_listener_ = {
+    ShellWayland::handle_ping, ShellWayland::handle_configure,
+    ShellWayland::handle_popup_done};
+
+void ShellWayland::handle_global(void *data, struct wl_registry *registry,
+                                 uint32_t id, const char *interface,
+                                 uint32_t version UNUSED) {
+    ShellWayland *_this = static_cast<ShellWayland *>(data);
+
+    if (!strcmp(interface, "wl_compositor"))
+        _this->compositor_ = static_cast<struct wl_compositor *>(
+            wl_registry_bind(registry, id, &wl_compositor_interface, 3));
+    /* Todo: When xdg_shell protocol has stablized, we should move wl_shell tp
+     * xdg_shell */
+    else if (!strcmp(interface, "wl_shell"))
+        _this->shell_ = static_cast<struct wl_shell *>(
+            wl_registry_bind(registry, id, &wl_shell_interface, 1));
+}
+
+void ShellWayland::handle_global_remove(void *data UNUSED,
+                                        struct wl_registry *registry UNUSED,
+                                        uint32_t name UNUSED) {}
+
+void ShellWayland::handle_ping(void *data UNUSED,
+                               struct wl_shell_surface *shell_surface,
+                               uint32_t serial) {
+    wl_shell_surface_pong(shell_surface, serial);
+}
+
+void ShellWayland::handle_configure(
+    void *data UNUSED, struct wl_shell_surface *shell_surface UNUSED,
+    uint32_t edges UNUSED, int32_t width UNUSED, int32_t height UNUSED) {}
+
+void ShellWayland::handle_popup_done(
+    void *data UNUSED, struct wl_shell_surface *shell_surface UNUSED) {}
+
+ShellWayland::ShellWayland(Game &game) : Shell(game) {
+    instance_extensions_.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
+
+    init_connection();
+    init_vk();
+}
+
+ShellWayland::~ShellWayland() {
+    cleanup_vk();
+    dlclose(lib_handle_);
+
+    if (shell_surface_)
+        wl_shell_surface_destroy(shell_surface_);
+    if (surface_)
+        wl_surface_destroy(surface_);
+    if (shell_)
+        wl_shell_destroy(shell_);
+    if (compositor_)
+        wl_compositor_destroy(compositor_);
+    if (registry_)
+        wl_registry_destroy(registry_);
+    if (display_)
+        wl_display_disconnect(display_);
+}
+
+void ShellWayland::init_connection() {
+    try {
+        display_ = wl_display_connect(NULL);
+        if (!display_)
+            throw std::runtime_error("failed to connect to the display server");
+
+        registry_ = wl_display_get_registry(display_);
+        if (!registry_)
+            throw std::runtime_error("failed to get registry");
+
+        wl_registry_add_listener(registry_, &registry_listener_, this);
+        wl_display_roundtrip(display_);
+
+        if (!compositor_)
+            throw std::runtime_error("failed to bind compositor");
+
+        if (!shell_)
+            throw std::runtime_error("failed to bind shell");
+    } catch (...) {
+        if (shell_)
+            wl_shell_destroy(shell_);
+        if (compositor_)
+            wl_compositor_destroy(compositor_);
+        if (registry_)
+            wl_registry_destroy(registry_);
+        if (display_)
+            wl_display_disconnect(display_);
+
+        throw;
+    }
+}
+
+void ShellWayland::create_window() {
+    surface_ = wl_compositor_create_surface(compositor_);
+    if (!surface_)
+        throw std::runtime_error("failed to create surface");
+
+    shell_surface_ = wl_shell_get_shell_surface(shell_, surface_);
+    if (!shell_surface_)
+        throw std::runtime_error("failed to shell_surface");
+
+    wl_shell_surface_add_listener(shell_surface_, &shell_surface_listener_,
+                                  this);
+    // set title
+    wl_shell_surface_set_title(shell_surface_, settings_.name.c_str());
+    wl_shell_surface_set_toplevel(shell_surface_);
+}
+
+PFN_vkGetInstanceProcAddr ShellWayland::load_vk() {
+    const char filename[] = "libvulkan.so";
+    void *handle, *symbol;
+
+#ifdef UNINSTALLED_LOADER
+    handle = dlopen(UNINSTALLED_LOADER, RTLD_LAZY);
+    if (!handle)
+        handle = dlopen(filename, RTLD_LAZY);
+#else
+    handle = dlopen(filename, RTLD_LAZY);
+#endif
+
+    if (handle)
+        symbol = dlsym(handle, "vkGetInstanceProcAddr");
+
+    if (!handle || !symbol) {
+        std::stringstream ss;
+        ss << "failed to load " << dlerror();
+
+        if (handle)
+            dlclose(handle);
+
+        throw std::runtime_error(ss.str());
+    }
+
+    lib_handle_ = handle;
+
+    return reinterpret_cast<PFN_vkGetInstanceProcAddr>(symbol);
+}
+
+bool ShellWayland::can_present(VkPhysicalDevice phy, uint32_t queue_family) {
+    return vk::GetPhysicalDeviceWaylandPresentationSupportKHR(phy, queue_family,
+                                                              display_);
+}
+
+VkSurfaceKHR ShellWayland::create_surface(VkInstance instance) {
+    VkWaylandSurfaceCreateInfoKHR surface_info = {};
+    surface_info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
+    surface_info.display = display_;
+    surface_info.surface = surface_;
+
+    VkSurfaceKHR surface;
+    vk::assert_success(vk::CreateWaylandSurfaceKHR(instance, &surface_info,
+                                                   nullptr, &surface));
+
+    return surface;
+}
+
+void ShellWayland::loop_wait() {
+    while (true) {
+        if (quit_)
+            break;
+
+        acquire_back_buffer();
+        present_back_buffer();
+    }
+}
+
+void ShellWayland::loop_poll() {
+    PosixTimer timer;
+
+    double current_time = timer.get();
+    double profile_start_time = current_time;
+    int profile_present_count = 0;
+
+    while (true) {
+        if (quit_)
+            break;
+
+        acquire_back_buffer();
+
+        double t = timer.get();
+        add_game_time(static_cast<float>(t - current_time));
+
+        present_back_buffer();
+
+        current_time = t;
+
+        profile_present_count++;
+        if (current_time - profile_start_time >= 5.0) {
+            const double fps =
+                profile_present_count / (current_time - profile_start_time);
+            std::stringstream ss;
+            ss << profile_present_count << " presents in "
+               << current_time - profile_start_time << " seconds "
+               << "(FPS: " << fps << ")";
+            log(LOG_INFO, ss.str().c_str());
+
+            profile_start_time = current_time;
+            profile_present_count = 0;
+        }
+    }
+}
+
+void ShellWayland::run() {
+    create_window();
+    create_context();
+    resize_swapchain(settings_.initial_width, settings_.initial_height);
+
+    quit_ = false;
+    if (settings_.animate)
+        loop_poll();
+    else
+        loop_wait();
+
+    destroy_context();
+}
diff --git a/demos/smoke/ShellWayland.h b/demos/smoke/ShellWayland.h
new file mode 100644
index 0000000..ab7f279
--- /dev/null
+++ b/demos/smoke/ShellWayland.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * Licensed under the Apache 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 SHELL_WAYLAND_H
+#define SHELL_WAYLAND_H
+
+#include "Shell.h"
+
+class ShellWayland : public Shell {
+  public:
+    ShellWayland(Game &game);
+    ~ShellWayland();
+
+    void run();
+    void quit() { quit_ = true; }
+
+  private:
+    void init_connection();
+
+    PFN_vkGetInstanceProcAddr load_vk();
+    bool can_present(VkPhysicalDevice phy, uint32_t queue_family);
+
+    void create_window();
+    VkSurfaceKHR create_surface(VkInstance instance);
+
+    void loop_wait();
+    void loop_poll();
+
+    void *lib_handle_;
+    bool quit_;
+
+    struct wl_display *display_;
+    struct wl_registry *registry_;
+    struct wl_compositor *compositor_;
+    struct wl_shell *shell_;
+    struct wl_surface *surface_;
+    struct wl_shell_surface *shell_surface_;
+
+    static void handle_global(void *data, struct wl_registry *registry,
+                              uint32_t id, const char *interface,
+                              uint32_t version);
+    static void handle_global_remove(void *data, struct wl_registry *registry,
+                                     uint32_t name);
+    static void handle_ping(void *data, struct wl_shell_surface *shell_surface,
+                            uint32_t serial);
+    static void handle_configure(void *data,
+                                 struct wl_shell_surface *shell_surface,
+                                 uint32_t edges, int32_t width, int32_t height);
+    static void handle_popup_done(void *data,
+                                  struct wl_shell_surface *shell_surface);
+
+    static const struct wl_registry_listener registry_listener_;
+    static const struct wl_shell_surface_listener shell_surface_listener_;
+};
+
+#endif // SHELL_WAYLAND_H
diff --git a/demos/smoke/generate-dispatch-table b/demos/smoke/generate-dispatch-table
index 07804b6..2158fa8 100755
--- a/demos/smoke/generate-dispatch-table
+++ b/demos/smoke/generate-dispatch-table
@@ -108,7 +108,6 @@
     Command(name='EnumerateInstanceExtensionProperties', dispatch=None),
     Command(name='EnumerateDeviceExtensionProperties', dispatch='VkPhysicalDevice'),
     Command(name='EnumerateInstanceLayerProperties', dispatch=None),
-    Command(name='EnumerateDeviceLayerProperties', dispatch='VkPhysicalDevice'),
     Command(name='GetDeviceQueue', dispatch='VkDevice'),
     Command(name='QueueSubmit', dispatch='VkQueue'),
     Command(name='QueueWaitIdle', dispatch='VkQueue'),
diff --git a/demos/tri.c b/demos/tri.c
index 441eddc..9baa23a 100644
--- a/demos/tri.c
+++ b/demos/tri.c
@@ -21,6 +21,7 @@
  * Author: Ian Elliott <ian@LunarG.com>
  * Author: Jon Ashburn <jon@lunarg.com>
  * Author: Piers Daniell <pdaniell@nvidia.com>
+ * Author: Gwan-gyeong Mun <elongbug@gmail.com>
  */
 /*
  * Draw a textured triangle with depth testing.  This is written against Intel
@@ -63,10 +64,17 @@
 #define U_ASSERT_ONLY
 #endif
 
+#if defined(__GNUC__)
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
+
 #ifdef _WIN32
 #define ERR_EXIT(err_msg, err_class)                                           \
     do {                                                                       \
-        MessageBox(NULL, err_msg, err_class, MB_OK);                           \
+        if (!demo->suppress_popups)                                            \
+            MessageBox(NULL, err_msg, err_class, MB_OK);                       \
         exit(1);                                                               \
     } while (0)
 #elif defined __ANDROID__
@@ -119,44 +127,6 @@
 static int validation_error = 0;
 
 VKAPI_ATTR VkBool32 VKAPI_CALL
-dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
-        uint64_t srcObject, size_t location, int32_t msgCode,
-        const char *pLayerPrefix, const char *pMsg, void *pUserData) {
-    char *message = (char *)malloc(strlen(pMsg) + 100);
-
-    assert(message);
-
-    validation_error = 1;
-
-    if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
-        sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode,
-                pMsg);
-    } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
-        sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode,
-                pMsg);
-    } else {
-        return false;
-    }
-
-#ifdef _WIN32
-    MessageBox(NULL, message, "Alert", MB_OK);
-#else
-    printf("%s\n", message);
-    fflush(stdout);
-#endif
-    free(message);
-
-    /*
-     * false indicates that layer should not bail-out of an
-     * API call that had validation failures. This may mean that the
-     * app dies inside the driver due to invalid parameter(s).
-     * That's what would happen without validation layers, so we'll
-     * keep that behavior here.
-     */
-    return false;
-}
-
-VKAPI_ATTR VkBool32 VKAPI_CALL
 BreakCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
               uint64_t srcObject, size_t location, int32_t msgCode,
               const char *pLayerPrefix, const char *pMsg,
@@ -182,17 +152,26 @@
     HINSTANCE connection;        // hInstance - Windows Instance
     char name[APP_NAME_STR_LEN]; // Name to put on the window/icon
     HWND window;                 // hWnd - window handle
+    POINT minsize;               // minimum window size
 #elif defined(VK_USE_PLATFORM_XCB_KHR)
     xcb_connection_t *connection;
     xcb_screen_t *screen;
     xcb_window_t window;
     xcb_intern_atom_reply_t *atom_wm_delete_window;
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    struct wl_display *display;
+    struct wl_registry *registry;
+    struct wl_compositor *compositor;
+    struct wl_surface *window;
+    struct wl_shell *shell;
+    struct wl_shell_surface *shell_surface;
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
     ANativeWindow* window;
 #endif
     VkSurfaceKHR surface;
     bool prepared;
     bool use_staging_buffer;
+    bool suppress_popups;
 
     VkInstance inst;
     VkPhysicalDevice gpu;
@@ -206,7 +185,7 @@
     uint32_t enabled_extension_count;
     uint32_t enabled_layer_count;
     char *extension_names[64];
-    char *device_validation_layers[64];
+    char *enabled_layers[64];
 
     int width, height;
     VkFormat format;
@@ -285,6 +264,46 @@
     uint32_t queue_count;
 };
 
+VKAPI_ATTR VkBool32 VKAPI_CALL
+dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
+    uint64_t srcObject, size_t location, int32_t msgCode,
+    const char *pLayerPrefix, const char *pMsg, void *pUserData) {
+    char *message = (char *)malloc(strlen(pMsg) + 100);
+
+    assert(message);
+
+    validation_error = 1;
+
+    if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+        sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode,
+            pMsg);
+    } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
+        sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode,
+            pMsg);
+    } else {
+        return false;
+    }
+
+#ifdef _WIN32
+    struct demo *demo = (struct demo*) pUserData;
+    if (!demo->suppress_popups)
+        MessageBox(NULL, message, "Alert", MB_OK);
+#else
+    printf("%s\n", message);
+    fflush(stdout);
+#endif
+    free(message);
+
+    /*
+    * false indicates that layer should not bail-out of an
+    * API call that had validation failures. This may mean that the
+    * app dies inside the driver due to invalid parameter(s).
+    * That's what would happen without validation layers, so we'll
+    * keep that behavior here.
+    */
+    return false;
+}
+
 // Forward declaration:
 static void demo_resize(struct demo *demo);
 
@@ -358,21 +377,11 @@
         err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->setup_cmd);
         assert(!err);
 
-        VkCommandBufferInheritanceInfo cmd_buf_hinfo = {
-            .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
-            .pNext = NULL,
-            .renderPass = VK_NULL_HANDLE,
-            .subpass = 0,
-            .framebuffer = VK_NULL_HANDLE,
-            .occlusionQueryEnable = VK_FALSE,
-            .queryFlags = 0,
-            .pipelineStatistics = 0,
-        };
         VkCommandBufferBeginInfo cmd_buf_info = {
             .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
             .pNext = NULL,
             .flags = 0,
-            .pInheritanceInfo = &cmd_buf_hinfo,
+            .pInheritanceInfo = NULL,
         };
         err = vkBeginCommandBuffer(demo->setup_cmd, &cmd_buf_info);
         assert(!err);
@@ -419,21 +428,11 @@
 }
 
 static void demo_draw_build_cmd(struct demo *demo) {
-    const VkCommandBufferInheritanceInfo cmd_buf_hinfo = {
-        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
-        .pNext = NULL,
-        .renderPass = VK_NULL_HANDLE,
-        .subpass = 0,
-        .framebuffer = VK_NULL_HANDLE,
-        .occlusionQueryEnable = VK_FALSE,
-        .queryFlags = 0,
-        .pipelineStatistics = 0,
-    };
     const VkCommandBufferBeginInfo cmd_buf_info = {
         .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
         .pNext = NULL,
         .flags = 0,
-        .pInheritanceInfo = &cmd_buf_hinfo,
+        .pInheritanceInfo = NULL,
     };
     const VkClearValue clear_values[2] = {
             [0] = {.color.float32 = {0.2f, 0.2f, 0.2f, 0.2f}},
@@ -526,20 +525,24 @@
 
 static void demo_draw(struct demo *demo) {
     VkResult U_ASSERT_ONLY err;
-    VkSemaphore presentCompleteSemaphore;
-    VkSemaphoreCreateInfo presentCompleteSemaphoreCreateInfo = {
+    VkSemaphore imageAcquiredSemaphore, drawCompleteSemaphore;
+    VkSemaphoreCreateInfo semaphoreCreateInfo = {
         .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
         .pNext = NULL,
         .flags = 0,
     };
 
-    err = vkCreateSemaphore(demo->device, &presentCompleteSemaphoreCreateInfo,
-                            NULL, &presentCompleteSemaphore);
+    err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo,
+                            NULL, &imageAcquiredSemaphore);
+    assert(!err);
+
+    err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo,
+                            NULL, &drawCompleteSemaphore);
     assert(!err);
 
     // Get the index of the next available swapchain image:
     err = demo->fpAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX,
-                                      presentCompleteSemaphore,
+                                      imageAcquiredSemaphore,
                                       (VkFence)0, // TODO: Show use of fence
                                       &demo->current_buffer);
     if (err == VK_ERROR_OUT_OF_DATE_KHR) {
@@ -547,7 +550,8 @@
         // must be recreated:
         demo_resize(demo);
         demo_draw(demo);
-        vkDestroySemaphore(demo->device, presentCompleteSemaphore, NULL);
+        vkDestroySemaphore(demo->device, imageAcquiredSemaphore, NULL);
+        vkDestroySemaphore(demo->device, drawCompleteSemaphore, NULL);
         return;
     } else if (err == VK_SUBOPTIMAL_KHR) {
         // demo->swapchain is not as optimal as it could be, but the platform's
@@ -570,12 +574,12 @@
     VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
                                 .pNext = NULL,
                                 .waitSemaphoreCount = 1,
-                                .pWaitSemaphores = &presentCompleteSemaphore,
+                                .pWaitSemaphores = &imageAcquiredSemaphore,
                                 .pWaitDstStageMask = &pipe_stage_flags,
                                 .commandBufferCount = 1,
                                 .pCommandBuffers = &demo->draw_cmd,
-                                .signalSemaphoreCount = 0,
-                                .pSignalSemaphores = NULL};
+                                .signalSemaphoreCount = 1,
+                                .pSignalSemaphores = &drawCompleteSemaphore};
 
     err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence);
     assert(!err);
@@ -586,6 +590,8 @@
         .swapchainCount = 1,
         .pSwapchains = &demo->swapchain,
         .pImageIndices = &demo->current_buffer,
+        .waitSemaphoreCount = 1,
+        .pWaitSemaphores = &drawCompleteSemaphore,
     };
 
     // TBD/TODO: SHOULD THE "present" PARAMETER BE "const" IN THE HEADER?
@@ -604,7 +610,8 @@
     err = vkQueueWaitIdle(demo->queue);
     assert(err == VK_SUCCESS);
 
-    vkDestroySemaphore(demo->device, presentCompleteSemaphore, NULL);
+    vkDestroySemaphore(demo->device, imageAcquiredSemaphore, NULL);
+    vkDestroySemaphore(demo->device, drawCompleteSemaphore, NULL);
 }
 
 static void demo_prepare_buffers(struct demo *demo) {
@@ -1592,6 +1599,9 @@
             demo_run(&demo);
             break;
         }
+    case WM_GETMINMAXINFO:     // set window's minimum size
+        ((MINMAXINFO*)lParam)->ptMinTrackSize = demo.minsize;
+        return 0;
     case WM_SIZE:
         // Resize the application to the new window size, except when
         // it was minimized. Vulkan doesn't support images or swapchains
@@ -1599,6 +1609,9 @@
         if (wParam != SIZE_MINIMIZED) {
             demo.width = lParam & 0xffff;
             demo.height = lParam & 0xffff0000 >> 16;
+            
+            if (demo.height < 64) demo.height = 64;
+
             demo_resize(&demo);
         }
         break;
@@ -1652,6 +1665,9 @@
         fflush(stdout);
         exit(1);
     }
+    // Window client area size must be at least 1 pixel high, to prevent crash.
+    demo->minsize.x = GetSystemMetrics(SM_CXMINTRACK);
+    demo->minsize.y = GetSystemMetrics(SM_CYMINTRACK) + 1;
 }
 #elif defined(VK_USE_PLATFORM_XCB_KHR)
 static void demo_handle_event(struct demo *demo,
@@ -1752,6 +1768,63 @@
 
     xcb_map_window(demo->connection, demo->window);
 }
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+static void demo_run(struct demo *demo) {
+
+    while (!demo->quit) {
+        demo_draw(demo);
+
+        if (demo->depthStencil > 0.99f)
+            demo->depthIncrement = -0.001f;
+        if (demo->depthStencil < 0.8f)
+            demo->depthIncrement = 0.001f;
+
+        demo->depthStencil += demo->depthIncrement;
+
+        // Wait for work to finish before updating MVP.
+        vkDeviceWaitIdle(demo->device);
+        demo->curFrame++;
+        if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount)
+            demo->quit = true;
+    }
+}
+
+static void handle_ping(void *data UNUSED,
+                        struct wl_shell_surface *shell_surface,
+                        uint32_t serial) {
+    wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void handle_configure(void *data UNUSED,
+                             struct wl_shell_surface *shell_surface UNUSED,
+                             uint32_t edges UNUSED, int32_t width UNUSED,
+                             int32_t height UNUSED) {}
+
+static void handle_popup_done(void *data UNUSED,
+                              struct wl_shell_surface *shell_surface UNUSED) {}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+    handle_ping, handle_configure, handle_popup_done};
+
+static void demo_create_window(struct demo *demo) {
+    demo->window = wl_compositor_create_surface(demo->compositor);
+    if (!demo->window) {
+        printf("Can not create wayland_surface from compositor!\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    demo->shell_surface = wl_shell_get_shell_surface(demo->shell, demo->window);
+    if (!demo->shell_surface) {
+        printf("Can not get shell_surface from wayland_surface!\n");
+        fflush(stdout);
+        exit(1);
+    }
+    wl_shell_surface_add_listener(demo->shell_surface, &shell_surface_listener,
+                                  demo);
+    wl_shell_surface_set_toplevel(demo->shell_surface);
+    wl_shell_surface_set_title(demo->shell_surface, APP_SHORT_NAME);
+}
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
 static void demo_run(struct demo *demo) {
     if (!demo->prepared)
@@ -1796,7 +1869,7 @@
     VkResult err;
     uint32_t instance_extension_count = 0;
     uint32_t instance_layer_count = 0;
-    uint32_t device_validation_layer_count = 0;
+    uint32_t validation_layer_count = 0;
     char **instance_validation_layers = NULL;
     demo->enabled_extension_count = 0;
     demo->enabled_layer_count = 0;
@@ -1806,10 +1879,10 @@
     };
 
     char *instance_validation_layers_alt2[] = {
-        "VK_LAYER_GOOGLE_threading",     "VK_LAYER_LUNARG_parameter_validation",
-        "VK_LAYER_LUNARG_device_limits", "VK_LAYER_LUNARG_object_tracker",
-        "VK_LAYER_LUNARG_image",         "VK_LAYER_LUNARG_core_validation",
-        "VK_LAYER_LUNARG_swapchain",     "VK_LAYER_GOOGLE_unique_objects"
+        "VK_LAYER_GOOGLE_threading",       "VK_LAYER_LUNARG_parameter_validation",
+        "VK_LAYER_LUNARG_object_tracker",  "VK_LAYER_LUNARG_image",
+        "VK_LAYER_LUNARG_core_validation", "VK_LAYER_LUNARG_swapchain",
+        "VK_LAYER_GOOGLE_unique_objects"
     };
 
     /* Look for validation layers */
@@ -1834,8 +1907,8 @@
                     instance_layers);
             if (validation_found) {
                 demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
-                demo->device_validation_layers[0] = "VK_LAYER_LUNARG_standard_validation";
-                device_validation_layer_count = 1;
+                demo->enabled_layers[0] = "VK_LAYER_LUNARG_standard_validation";
+                validation_layer_count = 1;
             } else {
                 // use alternative set of validation layers
                 instance_validation_layers = instance_validation_layers_alt2;
@@ -1844,11 +1917,10 @@
                     ARRAY_SIZE(instance_validation_layers_alt2),
                     instance_validation_layers, instance_layer_count,
                     instance_layers);
-                device_validation_layer_count =
-                        ARRAY_SIZE(instance_validation_layers_alt2);
-                for (uint32_t i = 0; i < device_validation_layer_count; i++) {
-                    demo->device_validation_layers[i] =
-                            instance_validation_layers[i];
+                validation_layer_count =
+                    ARRAY_SIZE(instance_validation_layers_alt2);
+                for (uint32_t i = 0; i < validation_layer_count; i++) {
+                    demo->enabled_layers[i] = instance_validation_layers[i];
                 }
             }
             free(instance_layers);
@@ -1899,6 +1971,13 @@
                 demo->extension_names[demo->enabled_extension_count++] =
                     VK_KHR_XCB_SURFACE_EXTENSION_NAME;
             }
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+            if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
+                        instance_extensions[i].extensionName)) {
+                platformSurfaceExtFound = 1;
+                demo->extension_names[demo->enabled_extension_count++] =
+                    VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
+            }
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
             if (!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
                         instance_extensions[i].extensionName)) {
@@ -1946,6 +2025,14 @@
                  "look at the Getting Started guide for additional "
                  "information.\n",
                  "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+                 "the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+                 " extension.\n\nDo you have a compatible "
+                 "Vulkan installable client driver (ICD) installed?\nPlease "
+                 "look at the Getting Started guide for additional "
+                 "information.\n",
+                 "vkCreateInstance Failure");
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
         ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
                  "the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
@@ -2015,41 +2102,6 @@
                  "vkEnumeratePhysicalDevices Failure");
     }
 
-    /* Look for validation layers */
-    if (demo->validate) {
-        validation_found = 0;
-        demo->enabled_layer_count = 0;
-        uint32_t device_layer_count = 0;
-        err =
-                vkEnumerateDeviceLayerProperties(demo->gpu, &device_layer_count, NULL);
-        assert(!err);
-
-        if (device_layer_count > 0) {
-            VkLayerProperties *device_layers =
-                    malloc(sizeof (VkLayerProperties) * device_layer_count);
-            err = vkEnumerateDeviceLayerProperties(demo->gpu, &device_layer_count,
-                    device_layers);
-            assert(!err);
-
-
-            validation_found = demo_check_layers(device_validation_layer_count,
-                    demo->device_validation_layers,
-                    device_layer_count,
-                    device_layers);
-            demo->enabled_layer_count = device_validation_layer_count;
-
-            free(device_layers);
-        }
-
-        if (!validation_found) {
-            ERR_EXIT("vkEnumerateDeviceLayerProperties failed to find "
-                    "a required validation layer.\n\n"
-                    "Please look at the Getting Started guide for additional "
-                    "information.\n",
-                    "vkCreateDevice Failure");
-        }
-    }
-
     /* Look for device extensions */
     uint32_t device_extension_count = 0;
     VkBool32 swapchainExtFound = 0;
@@ -2120,7 +2172,7 @@
         dbgCreateInfo.flags =
             VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
         dbgCreateInfo.pfnCallback = demo->use_break ? BreakCallback : dbgFunc;
-        dbgCreateInfo.pUserData = NULL;
+        dbgCreateInfo.pUserData = demo;
         dbgCreateInfo.pNext = NULL;
         err = demo->CreateDebugReportCallback(demo->inst, &dbgCreateInfo, NULL,
                                               &demo->msg_callback);
@@ -2192,11 +2244,8 @@
         .pNext = NULL,
         .queueCreateInfoCount = 1,
         .pQueueCreateInfos = &queue,
-        .enabledLayerCount = demo->enabled_layer_count,
-        .ppEnabledLayerNames =
-            (const char *const *)((demo->validate)
-                                      ? demo->device_validation_layers
-                                      : NULL),
+        .enabledLayerCount = 0,
+        .ppEnabledLayerNames = NULL,
         .enabledExtensionCount = demo->enabled_extension_count,
         .ppEnabledExtensionNames = (const char *const *)demo->extension_names,
         .pEnabledFeatures = &features,
@@ -2230,6 +2279,16 @@
     createInfo.window = demo->window;
 
     err = vkCreateXcbSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    VkWaylandSurfaceCreateInfoKHR createInfo;
+    createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
+    createInfo.pNext = NULL;
+    createInfo.flags = 0;
+    createInfo.display = demo->display;
+    createInfo.surface = demo->window;
+
+    err = vkCreateWaylandSurfaceKHR(demo->inst, &createInfo, NULL,
+                                    &demo->surface);
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
     VkAndroidSurfaceCreateInfoKHR createInfo;
     createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
@@ -2329,6 +2388,29 @@
     vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties);
 }
 
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) && !defined(VK_USE_PLATFORM_XCB_KHR)
+static void registry_handle_global(void *data, struct wl_registry *registry,
+                                   uint32_t name, const char *interface,
+                                   uint32_t version UNUSED) {
+    struct demo *demo = data;
+    if (strcmp(interface, "wl_compositor") == 0) {
+        demo->compositor =
+            wl_registry_bind(registry, name, &wl_compositor_interface, 3);
+        /* Todo: When xdg_shell protocol has stablized, we should move wl_shell
+         * tp xdg_shell */
+    } else if (strcmp(interface, "wl_shell") == 0) {
+        demo->shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
+    }
+}
+
+static void registry_handle_global_remove(void *data UNUSED,
+                                          struct wl_registry *registry UNUSED,
+                                          uint32_t name UNUSED) {}
+
+static const struct wl_registry_listener registry_listener = {
+    registry_handle_global, registry_handle_global_remove};
+#endif
+
 static void demo_init_connection(struct demo *demo) {
 #if defined(VK_USE_PLATFORM_XCB_KHR)
     const xcb_setup_t *setup;
@@ -2336,7 +2418,7 @@
     int scr;
 
     demo->connection = xcb_connect(NULL, &scr);
-    if (demo->connection == NULL) {
+    if (xcb_connection_has_error(demo->connection) > 0) {
         printf("Cannot find a compatible Vulkan installable client driver "
                "(ICD).\nExiting ...\n");
         fflush(stdout);
@@ -2349,6 +2431,19 @@
         xcb_screen_next(&iter);
 
     demo->screen = iter.data;
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    demo->display = wl_display_connect(NULL);
+
+    if (demo->display == NULL) {
+        printf("Cannot find a compatible Vulkan installable client driver "
+               "(ICD).\nExiting ...\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    demo->registry = wl_display_get_registry(demo->display);
+    wl_registry_add_listener(demo->registry, &registry_listener, demo);
+    wl_display_dispatch(demo->display);
 #endif // _WIN32
 }
 
@@ -2376,9 +2471,13 @@
             i++;
             continue;
         }
+        if (strcmp(argv[i], "--suppress_popups") == 0) {
+            demo->suppress_popups = true;
+            continue;
+        }
 
         fprintf(stderr, "Usage:\n  %s [--use_staging] [--validate] [--break] "
-                        "[--c <framecount>]\n",
+                        "[--c <framecount>] [--suppress_popups]\n",
                 APP_SHORT_NAME);
         fflush(stderr);
         exit(1);
@@ -2449,6 +2548,13 @@
     xcb_destroy_window(demo->connection, demo->window);
     xcb_disconnect(demo->connection);
     free(demo->atom_wm_delete_window);
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    wl_shell_surface_destroy(demo->shell_surface);
+    wl_surface_destroy(demo->window);
+    wl_shell_destroy(demo->shell);
+    wl_compositor_destroy(demo->compositor);
+    wl_registry_destroy(demo->registry);
+    wl_display_disconnect(demo->display);
 #endif
 }
 
@@ -2658,7 +2764,7 @@
 
 }
 
-#elif defined(VK_USE_PLATFORM_XCB_KHR)
+#elif defined(VK_USE_PLATFORM_XCB_KHR) | defined(VK_USE_PLATFORM_WAYLAND_KHR)
 
 int main(const int argc, const char *argv[]) {
     struct demo demo;
diff --git a/demos/vulkaninfo.c b/demos/vulkaninfo.c
index 7754625..642f3db 100644
--- a/demos/vulkaninfo.c
+++ b/demos/vulkaninfo.c
@@ -18,19 +18,24 @@
  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
  * Author: David Pinedo <david@lunarg.com>
  * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Rene Lindsay <rene@lunarg.com>
  */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
 #include <assert.h>
 #include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #ifdef _WIN32
 #include <fcntl.h>
 #include <io.h>
 #endif // _WIN32
 
+#ifdef __linux__
+#include <X11/Xutil.h>
+#endif
+
 #include <vulkan/vulkan.h>
 
 #define ERR(err)                                                               \
@@ -51,7 +56,7 @@
 
 #define WAIT_FOR_CONSOLE_DESTROY                                               \
     do {                                                                       \
-        if (ConsoleIsExclusive())                                                    \
+        if (ConsoleIsExclusive())                                              \
             Sleep(INFINITE);                                                   \
     } while (0)
 #else
@@ -100,7 +105,39 @@
     uint32_t global_layer_count;
     struct layer_extension_list *global_layers;
     uint32_t global_extension_count;
-    VkExtensionProperties *global_extensions;
+    VkExtensionProperties *global_extensions; // Instance Extensions
+
+    PFN_vkGetPhysicalDeviceSurfaceSupportKHR
+        vkGetPhysicalDeviceSurfaceSupportKHR;
+    PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
+        vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+    PFN_vkGetPhysicalDeviceSurfaceFormatsKHR
+        vkGetPhysicalDeviceSurfaceFormatsKHR;
+    PFN_vkGetPhysicalDeviceSurfacePresentModesKHR
+        vkGetPhysicalDeviceSurfacePresentModesKHR;
+
+    VkSurfaceKHR surface;
+    int width, height;
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    HINSTANCE hInstance; // Windows Instance
+    HWND hWnd;           // window handle
+#endif
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    xcb_connection_t *xcb_connection;
+    xcb_screen_t *xcb_screen;
+    xcb_window_t xcb_window;
+#endif
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    Display *xlib_display;
+    Window xlib_window;
+#endif
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR // TODO
+    ANativeWindow *window;
+#endif
 };
 
 struct app_gpu {
@@ -117,9 +154,6 @@
     VkPhysicalDeviceFeatures features;
     VkPhysicalDevice limits;
 
-    uint32_t device_layer_count;
-    struct layer_extension_list *device_layers;
-
     uint32_t device_extension_count;
     VkExtensionProperties *device_extensions;
 
@@ -449,49 +483,7 @@
     };
     VkResult U_ASSERT_ONLY err;
 
-    uint32_t count = 0;
-
-    /* Scan layers */
-    VkLayerProperties *device_layer_properties = NULL;
-    struct layer_extension_list *device_layers = NULL;
-
-    do {
-        err = vkEnumerateDeviceLayerProperties(gpu->obj, &count, NULL);
-        assert(!err);
-
-        if (device_layer_properties) {
-            free(device_layer_properties);
-        }
-        device_layer_properties = malloc(sizeof(VkLayerProperties) * count);
-        assert(device_layer_properties);
-
-        if (device_layers) {
-            free(device_layers);
-        }
-        device_layers = malloc(sizeof(struct layer_extension_list) * count);
-        assert(device_layers);
-
-        err = vkEnumerateDeviceLayerProperties(gpu->obj, &count,
-                                               device_layer_properties);
-    } while (err == VK_INCOMPLETE);
-    assert(!err);
-
-    gpu->device_layer_count = count;
-    gpu->device_layers = device_layers;
-
-    for (uint32_t i = 0; i < gpu->device_layer_count; i++) {
-        VkLayerProperties *src_info = &device_layer_properties[i];
-        struct layer_extension_list *dst_info = &gpu->device_layers[i];
-        memcpy(&dst_info->layer_properties, src_info,
-               sizeof(VkLayerProperties));
-
-        /* Save away layer extension info for report */
-        app_get_physical_device_layer_extensions(
-            gpu, src_info->layerName, &dst_info->extension_count,
-            &dst_info->extension_properties);
-    }
-    free(device_layer_properties);
-
+    // Device extensions
     app_get_physical_device_layer_extensions(
         gpu, NULL, &gpu->device_extension_count, &gpu->device_extensions);
 
@@ -524,6 +516,7 @@
 
     /* repeat get until VK_INCOMPLETE goes away */
     do {
+        // gets the extension count if the last parameter is NULL
         err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count,
                                                      NULL);
         assert(!err);
@@ -532,34 +525,17 @@
             free(ext_ptr);
         }
         ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties));
+        // gets the extension properties if the last parameter is not NULL
         err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count,
                                                      ext_ptr);
     } while (err == VK_INCOMPLETE);
     assert(!err);
-
     *extension_count = ext_count;
     *extension_properties = ext_ptr;
 }
 
-static void app_create_instance(struct app_instance *inst) {
-    const VkApplicationInfo app_info = {
-        .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
-        .pNext = NULL,
-        .pApplicationName = APP_SHORT_NAME,
-        .applicationVersion = 1,
-        .pEngineName = APP_SHORT_NAME,
-        .engineVersion = 1,
-        .apiVersion = VK_API_VERSION_1_0,
-    };
-    VkInstanceCreateInfo inst_info = {
-        .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
-        .pNext = NULL,
-        .pApplicationInfo = &app_info,
-        .enabledLayerCount = 0,
-        .ppEnabledLayerNames = NULL,
-        .enabledExtensionCount = 0,
-        .ppEnabledExtensionNames = NULL,
-    };
+/* Gets a list of layer and instance extensions */
+static void app_get_instance_extensions(struct app_instance *inst) {
     VkResult U_ASSERT_ONLY err;
 
     uint32_t count = 0;
@@ -598,18 +574,90 @@
         memcpy(&dst_info->layer_properties, src_info,
                sizeof(VkLayerProperties));
 
-        /* Save away layer extension info for report */
+        // Save away layer extension info for report
+        // Gets layer extensions, if first parameter is not NULL
         app_get_global_layer_extensions(src_info->layerName,
                                         &dst_info->extension_count,
                                         &dst_info->extension_properties);
     }
     free(global_layer_properties);
 
-    /* Collect global extensions */
+    // Collect global extensions
     inst->global_extension_count = 0;
+    // Gets instance extensions, if no layer was specified in the first
+    // paramteter
     app_get_global_layer_extensions(NULL, &inst->global_extension_count,
                                     &inst->global_extensions);
+}
 
+static void app_create_instance(struct app_instance *inst) {
+    app_get_instance_extensions(inst);
+
+//---Build a list of extensions to load---
+#define MAX_EXTENSIONS 4
+    uint32_t i = 0;
+    uint32_t ext_count = 0;
+    const char *ext_names[MAX_EXTENSIONS]; // array of string pointers to
+                                           // extension names
+    for (i = 0; (i < inst->global_extension_count); i++) {
+        const char *found_name = inst->global_extensions[i].extensionName;
+        if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME, found_name)) {
+            ext_names[ext_count++] = VK_KHR_SURFACE_EXTENSION_NAME;
+        }
+    }
+
+    if (ext_count)
+        for (i = 0; ((i < inst->global_extension_count) &&
+                     (ext_count < MAX_EXTENSIONS));
+             i++) {
+            const char *found_name = inst->global_extensions[i].extensionName;
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+            if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, found_name)) {
+                ext_names[ext_count++] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
+            }
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+            if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, found_name)) {
+                ext_names[ext_count++] = VK_KHR_XCB_SURFACE_EXTENSION_NAME;
+            }
+#endif
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+            if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, found_name)) {
+                ext_names[ext_count++] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
+            }
+#endif
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+            if (!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, found_name)) {
+                ext_names[ext_count++] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
+            }
+#endif
+        }
+    // If we don't find the KHR_SURFACE extension and at least one other
+    // device-specific extension,
+    // then give up on reporting presentable surface formats."
+    if (ext_count < 2)
+        ext_count = 0;
+    //----------------------------------------
+
+    const VkApplicationInfo app_info = {
+        .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+        .pNext = NULL,
+        .pApplicationName = APP_SHORT_NAME,
+        .applicationVersion = 1,
+        .pEngineName = APP_SHORT_NAME,
+        .engineVersion = 1,
+        .apiVersion = VK_API_VERSION_1_0,
+    };
+
+    VkInstanceCreateInfo inst_info = {
+        .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+        .pNext = NULL,
+        .pApplicationInfo = &app_info,
+        .enabledLayerCount = 0,
+        .ppEnabledLayerNames = NULL,
+        .enabledExtensionCount = ext_count,
+        .ppEnabledExtensionNames = ext_names,
+    };
 
     VkDebugReportCallbackCreateInfoEXT dbg_info;
     memset(&dbg_info, 0, sizeof(dbg_info));
@@ -620,6 +668,7 @@
     dbg_info.pfnCallback = dbg_callback;
     inst_info.pNext = &dbg_info;
 
+    VkResult U_ASSERT_ONLY err;
     err = vkCreateInstance(&inst_info, NULL, &inst->instance);
     if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
         printf("Cannot create Vulkan instance.\n");
@@ -627,8 +676,24 @@
     } else if (err) {
         ERR_EXIT(err);
     }
+
+    if (ext_count > 0) {
+//--Load Extensions--
+#define GET_INSTANCE_PROC_ADDR(ENTRYPOINT)                                     \
+    {                                                                          \
+        inst->ENTRYPOINT =                                                     \
+            (void *)vkGetInstanceProcAddr(inst->instance, #ENTRYPOINT);        \
+    }
+        GET_INSTANCE_PROC_ADDR(vkGetPhysicalDeviceSurfaceSupportKHR)
+        GET_INSTANCE_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR)
+        GET_INSTANCE_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormatsKHR)
+        GET_INSTANCE_PROC_ADDR(vkGetPhysicalDeviceSurfacePresentModesKHR)
+#undef GET_INSTANCE_PROC_ADDR
+    }
 }
 
+//-----------------------------------------------------------
+
 static void app_destroy_instance(struct app_instance *inst) {
     free(inst->global_extensions);
     vkDestroyInstance(inst->instance, NULL);
@@ -691,6 +756,197 @@
 }
 
 // clang-format off
+
+//-----------------------------------------------------------
+
+//---------------------------Win32---------------------------
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+
+// MS-Windows event handling function:
+LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+    return (DefWindowProc(hWnd, uMsg, wParam, lParam));
+}
+
+static void app_create_win32_window(struct app_instance *inst) {
+    inst->hInstance = GetModuleHandle(NULL);
+
+    WNDCLASSEX win_class;
+
+    // Initialize the window class structure:
+    win_class.cbSize = sizeof(WNDCLASSEX);
+    win_class.style = CS_HREDRAW | CS_VREDRAW;
+    win_class.lpfnWndProc = WndProc;
+    win_class.cbClsExtra = 0;
+    win_class.cbWndExtra = 0;
+    win_class.hInstance = inst->hInstance;
+    win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+    win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
+    win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+    win_class.lpszMenuName = NULL;
+    win_class.lpszClassName = APP_SHORT_NAME;
+    win_class.hInstance = inst->hInstance;
+    win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
+    // Register window class:
+    if (!RegisterClassEx(&win_class)) {
+        // It didn't work, so try to give a useful error:
+        printf("Failed to register the window class!\n");
+        fflush(stdout);
+        exit(1);
+    }
+    // Create window with the registered class:
+    RECT wr = { 0, 0, inst->width, inst->height };
+    AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
+    inst->hWnd = CreateWindowEx(0,
+        APP_SHORT_NAME,       // class name
+        APP_SHORT_NAME,       // app name
+        //WS_VISIBLE | WS_SYSMENU |
+        WS_OVERLAPPEDWINDOW,  // window style
+        100, 100,             // x/y coords
+        wr.right - wr.left,   // width
+        wr.bottom - wr.top,   // height
+        NULL,                 // handle to parent
+        NULL,                 // handle to menu
+        inst->hInstance,      // hInstance
+        NULL);                // no extra parameters
+    if (!inst->hWnd) {
+        // It didn't work, so try to give a useful error:
+        printf("Failed to create a window!\n");
+        fflush(stdout);
+        exit(1);
+    }
+}
+
+static void app_create_win32_surface(struct app_instance *inst) {
+    VkResult U_ASSERT_ONLY err;
+    VkWin32SurfaceCreateInfoKHR createInfo;
+    createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+    createInfo.pNext = NULL;
+    createInfo.flags = 0;
+    createInfo.hinstance = inst->hInstance;
+    createInfo.hwnd = inst->hWnd;
+    err = vkCreateWin32SurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface);
+    assert(!err);
+}
+
+static void app_destroy_win32_window(struct app_instance *inst) {
+    DestroyWindow(inst->hWnd);
+}
+#endif //VK_USE_PLATFORM_WIN32_KHR
+//-----------------------------------------------------------
+
+static void app_destroy_surface(struct app_instance *inst) { //same for all platforms
+    vkDestroySurfaceKHR(inst->instance, inst->surface, NULL);
+}
+
+//----------------------------XCB----------------------------
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+static void app_create_xcb_window(struct app_instance *inst) {
+  //--Init Connection--
+  const xcb_setup_t *setup;
+  xcb_screen_iterator_t iter;
+  int scr;
+
+  inst->xcb_connection = xcb_connect(NULL, &scr);
+  if (inst->xcb_connection == NULL) {
+      printf("XCB failed to connect to the X server.\nExiting ...\n");
+      fflush(stdout);
+      exit(1);
+  }
+
+  setup = xcb_get_setup(inst->xcb_connection);
+  iter = xcb_setup_roots_iterator(setup);
+  while (scr-- > 0)
+      xcb_screen_next(&iter);
+
+  inst->xcb_screen = iter.data;
+  //-------------------
+
+  inst->xcb_window = xcb_generate_id(inst->xcb_connection);
+  xcb_create_window(inst->xcb_connection, XCB_COPY_FROM_PARENT, inst->xcb_window,
+                    inst->xcb_screen->root, 0, 0, inst->width, inst->height, 0,
+                    XCB_WINDOW_CLASS_INPUT_OUTPUT, inst->xcb_screen->root_visual,
+                    0, NULL);
+
+  xcb_intern_atom_cookie_t cookie = xcb_intern_atom(inst->xcb_connection, 1, 12, "WM_PROTOCOLS");
+  xcb_intern_atom_reply_t *reply =  xcb_intern_atom_reply(inst->xcb_connection, cookie, 0);
+  free(reply);
+}
+
+static void app_create_xcb_surface(struct app_instance *inst) {
+    VkResult U_ASSERT_ONLY err;
+    VkXcbSurfaceCreateInfoKHR xcb_createInfo;
+    xcb_createInfo.sType      = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
+    xcb_createInfo.pNext      = NULL;
+    xcb_createInfo.flags      = 0;
+    xcb_createInfo.connection = inst->xcb_connection;
+    xcb_createInfo.window     = inst->xcb_window;
+    err = vkCreateXcbSurfaceKHR(inst->instance, &xcb_createInfo, NULL, &inst->surface);
+    assert(!err);
+}
+
+static void app_destroy_xcb_window(struct app_instance *inst) {
+    xcb_destroy_window(inst->xcb_connection, inst->xcb_window);
+    xcb_disconnect(inst->xcb_connection);
+}
+#endif //VK_USE_PLATFORM_XCB_KHR
+//-----------------------------------------------------------
+
+//----------------------------XLib---------------------------
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+static void app_create_xlib_window(struct app_instance *inst) {
+    inst->xlib_display = XOpenDisplay(NULL);
+    long visualMask = VisualScreenMask;
+    int numberOfVisuals;
+
+    XVisualInfo vInfoTemplate={};
+    vInfoTemplate.screen = DefaultScreen(inst->xlib_display);
+    XVisualInfo *visualInfo = XGetVisualInfo(inst->xlib_display, visualMask,
+                                             &vInfoTemplate, &numberOfVisuals);
+    inst->xlib_window = XCreateWindow(
+                inst->xlib_display, RootWindow(inst->xlib_display, vInfoTemplate.screen), 0, 0,
+                inst->width, inst->height, 0, visualInfo->depth, InputOutput,
+                visualInfo->visual, 0, NULL);
+
+    XSync(inst->xlib_display,false);
+}
+
+static void app_create_xlib_surface(struct app_instance *inst) {
+    VkResult U_ASSERT_ONLY err;
+    VkXlibSurfaceCreateInfoKHR createInfo;
+    createInfo.sType  = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
+    createInfo.pNext  = NULL;
+    createInfo.flags  = 0;
+    createInfo.dpy    = inst->xlib_display;
+    createInfo.window = inst->xlib_window;
+    err = vkCreateXlibSurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface);
+    assert(!err);
+}
+
+static void app_destroy_xlib_window(struct app_instance *inst) {
+    XDestroyWindow(inst->xlib_display, inst->xlib_window);
+    XCloseDisplay(inst->xlib_display);
+}
+#endif //VK_USE_PLATFORM_XLIB_KHR
+//-----------------------------------------------------------
+
+static int app_dump_surface_formats(struct app_instance *inst, struct app_gpu *gpu){
+    // Get the list of VkFormat's that are supported:
+  VkResult U_ASSERT_ONLY err;
+  uint32_t formatCount=0;
+  err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &formatCount, NULL);
+  assert(!err);
+  VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
+  err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &formatCount, surfFormats);
+  assert(!err);
+  printf("Format count = %d\n",formatCount);
+  uint32_t i;
+  for(i=0;i<formatCount;i++) printf("\t%s\n",vk_format_string(surfFormats[i].format));
+  printf("\n");
+  fflush(stdout);
+  return formatCount;
+}
+
 static void app_dev_dump_format_props(const struct app_dev *dev, VkFormat fmt)
 {
     const VkFormatProperties *props = &dev->format_props[fmt];
@@ -737,6 +993,8 @@
 static void
 app_dev_dump(const struct app_dev *dev)
 {
+    printf("Format Properties:\n");
+    printf("==================");
     VkFormat fmt;
 
     for (fmt = 0; fmt < VK_FORMAT_RANGE_SIZE; fmt++) {
@@ -898,19 +1156,19 @@
     printf("\t\tmaxViewports                            = %u\n",                 limits->maxViewports                           );
     printf("\t\tmaxViewportDimensions[0]                = %u\n",                 limits->maxViewportDimensions[0]               );
     printf("\t\tmaxViewportDimensions[1]                = %u\n",                 limits->maxViewportDimensions[1]               );
-    printf("\t\tviewportBoundsRange[0]                  = %f\n",                 limits->viewportBoundsRange[0]                 );
-    printf("\t\tviewportBoundsRange[1]                  = %f\n",                 limits->viewportBoundsRange[1]                 );
+    printf("\t\tviewportBoundsRange[0]                  =%13f\n",                 limits->viewportBoundsRange[0]                 );
+    printf("\t\tviewportBoundsRange[1]                  =%13f\n",                 limits->viewportBoundsRange[1]                 );
     printf("\t\tviewportSubPixelBits                    = %u\n",                 limits->viewportSubPixelBits                   );
     printf("\t\tminMemoryMapAlignment                   = " PRINTF_SIZE_T_SPECIFIER "\n", limits->minMemoryMapAlignment         );
     printf("\t\tminTexelBufferOffsetAlignment           = 0x%" PRIxLEAST64 "\n", limits->minTexelBufferOffsetAlignment          );
     printf("\t\tminUniformBufferOffsetAlignment         = 0x%" PRIxLEAST64 "\n", limits->minUniformBufferOffsetAlignment        );
     printf("\t\tminStorageBufferOffsetAlignment         = 0x%" PRIxLEAST64 "\n", limits->minStorageBufferOffsetAlignment        );
-    printf("\t\tminTexelOffset                          = 0x%" PRIxLEAST32 "\n", limits->minTexelOffset                         );
-    printf("\t\tmaxTexelOffset                          = 0x%" PRIxLEAST32 "\n", limits->maxTexelOffset                         );
-    printf("\t\tminTexelGatherOffset                    = 0x%" PRIxLEAST32 "\n", limits->minTexelGatherOffset                   );
-    printf("\t\tmaxTexelGatherOffset                    = 0x%" PRIxLEAST32 "\n", limits->maxTexelGatherOffset                   );
-    printf("\t\tminInterpolationOffset                  = %f\n",                 limits->minInterpolationOffset                 );
-    printf("\t\tmaxInterpolationOffset                  = %f\n",                 limits->maxInterpolationOffset                 );
+    printf("\t\tminTexelOffset                          =%3d\n",                 limits->minTexelOffset                         );
+    printf("\t\tmaxTexelOffset                          =%3d\n",                 limits->maxTexelOffset                         );
+    printf("\t\tminTexelGatherOffset                    =%3d\n",                 limits->minTexelGatherOffset                   );
+    printf("\t\tmaxTexelGatherOffset                    =%3d\n",                 limits->maxTexelGatherOffset                   );
+    printf("\t\tminInterpolationOffset                  =%9f\n",                 limits->minInterpolationOffset                 );
+    printf("\t\tmaxInterpolationOffset                  =%9f\n",                 limits->maxInterpolationOffset                 );
     printf("\t\tsubPixelInterpolationOffsetBits         = %u\n",                 limits->subPixelInterpolationOffsetBits        );
     printf("\t\tmaxFramebufferWidth                     = %u\n",                 limits->maxFramebufferWidth                    );
     printf("\t\tmaxFramebufferHeight                    = %u\n",                 limits->maxFramebufferHeight                   );
@@ -977,29 +1235,54 @@
     if (layer_name && (strlen(layer_name) > 0)) {
         printf("%s%s Extensions", indent, layer_name);
     } else {
-        printf("Extensions");
+        printf("%sExtensions", indent);
     }
     printf("\tcount = %d\n", extension_count);
     for (i = 0; i < extension_count; i++) {
         VkExtensionProperties const *ext_prop = &extension_properties[i];
 
         printf("%s\t", indent);
-        printf("%-32s: extension revision %2d\n", ext_prop->extensionName,
+        printf("%-36s: extension revision %2d\n", ext_prop->extensionName,
                ext_prop->specVersion);
     }
-    printf("\n");
     fflush(stdout);
 }
 
+// Returns true if the named extension is in the list of extensions.
+static bool has_extension(const char *extension_name,
+                          const uint32_t extension_count,
+                          const VkExtensionProperties *extension_properties) {
+    for (uint32_t i = 0; i < extension_count; i++) {
+        if (!strcmp(extension_name, extension_properties[i].extensionName))
+            return true;
+    }
+    return false;
+}
+
 static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) {
     const VkQueueFamilyProperties *props = &gpu->queue_props[id];
 
     printf("VkQueueFamilyProperties[%d]:\n", id);
-    printf("============================\n");
-    printf("\tqueueFlags         = %c%c%c\n",
-           (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '.',
-           (props->queueFlags & VK_QUEUE_COMPUTE_BIT ) ? 'C' : '.',
-           (props->queueFlags & VK_QUEUE_TRANSFER_BIT) ? 'D' : '.');
+    printf("===========================\n");
+    char *sep = ""; // separator character
+    printf("\tqueueFlags         = ");
+    if (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+        printf("GRAPHICS");
+        sep = " | ";
+    }
+    if (props->queueFlags & VK_QUEUE_COMPUTE_BIT) {
+        printf("%sCOMPUTE", sep);
+        sep = " | ";
+    }
+    if (props->queueFlags & VK_QUEUE_TRANSFER_BIT) {
+        printf("%sTRANSFER", sep);
+        sep = " | ";
+    }
+    if (props->queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) {
+        printf("%sSPARSE", sep);
+    }
+    printf("\n");
+
     printf("\tqueueCount         = %u\n", props->queueCount);
     printf("\ttimestampValidBits = %u\n", props->timestampValidBits);
     printf("\tminImageTransferGranularity = (%d, %d, %d)\n",
@@ -1018,30 +1301,35 @@
     for (uint32_t i = 0; i < props->memoryTypeCount; i++) {
         printf("\tmemoryTypes[%u] : \n", i);
         printf("\t\theapIndex     = %u\n", props->memoryTypes[i].heapIndex);
-        printf("\t\tpropertyFlags = 0x%" PRIxLEAST32 ":\n", props->memoryTypes[i].propertyFlags);
+        printf("\t\tpropertyFlags = 0x%" PRIxLEAST32 ":\n",
+               props->memoryTypes[i].propertyFlags);
 
-        //Print each named flag, if it is set.
-        VkFlags flags=props->memoryTypes[i].propertyFlags;
-#define PRINT_FLAG(FLAG) printf((flags & FLAG) ? "\t\t\t"#FLAG"\n" : "");
+        // Print each named flag, if it is set.
+        VkFlags flags = props->memoryTypes[i].propertyFlags;
+#define PRINT_FLAG(FLAG)                                                       \
+    if (flags & FLAG)                                                          \
+        printf("\t\t\t" #FLAG "\n");
         PRINT_FLAG(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
         PRINT_FLAG(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
         PRINT_FLAG(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
         PRINT_FLAG(VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
         PRINT_FLAG(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
-#undef  PRINT_FLAG
-
+#undef PRINT_FLAG
     }
     printf("\n");
     printf("\tmemoryHeapCount       = %u\n", props->memoryHeapCount);
     for (uint32_t i = 0; i < props->memoryHeapCount; i++) {
         printf("\tmemoryHeaps[%u] : \n", i);
         const VkDeviceSize memSize = props->memoryHeaps[i].size;
-        printf("\t\tsize          = " PRINTF_SIZE_T_SPECIFIER " (0x%" PRIxLEAST64 ")\n",
+        printf("\t\tsize          = " PRINTF_SIZE_T_SPECIFIER
+               " (0x%" PRIxLEAST64 ")\n",
                (size_t)memSize, memSize);
 
-        VkMemoryHeapFlags heapFlags=props->memoryHeaps[i].flags;
+        VkMemoryHeapFlags heapFlags = props->memoryHeaps[i].flags;
         printf("\t\tflags: \n\t\t\t");
-        printf((heapFlags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? "VK_MEMORY_HEAP_DEVICE_LOCAL_BIT\n" : "None\n");
+        printf((heapFlags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
+                   ? "VK_MEMORY_HEAP_DEVICE_LOCAL_BIT\n"
+                   : "None\n");
     }
     fflush(stdout);
 }
@@ -1049,37 +1337,14 @@
 static void app_gpu_dump(const struct app_gpu *gpu) {
     uint32_t i;
 
-    printf("Device Extensions and layers:\n");
-    printf("=============================\n");
+    printf("\nDevice Properties and Extensions :\n");
+    printf("==================================\n");
     printf("GPU%u\n", gpu->id);
     app_gpu_dump_props(gpu);
     printf("\n");
     app_dump_extensions("", "Device", gpu->device_extension_count,
                         gpu->device_extensions);
     printf("\n");
-    printf("Layers\tcount = %d\n", gpu->device_layer_count);
-    for (uint32_t i = 0; i < gpu->device_layer_count; i++) {
-        uint32_t major, minor, patch;
-        char spec_version[64], layer_version[64];
-        struct layer_extension_list const *layer_info = &gpu->device_layers[i];
-
-        extract_version(layer_info->layer_properties.specVersion, &major,
-                        &minor, &patch);
-        snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor,
-                 patch);
-        snprintf(layer_version, sizeof(layer_version), "%d",
-                 layer_info->layer_properties.implementationVersion);
-        printf("\t%s (%s) Vulkan version %s, layer version %s\n",
-               layer_info->layer_properties.layerName,
-               (char *)layer_info->layer_properties.description, spec_version,
-               layer_version);
-
-        app_dump_extensions("\t", layer_info->layer_properties.layerName,
-                            layer_info->extension_count,
-                            layer_info->extension_properties);
-        fflush(stdout);
-    }
-    printf("\n");
     for (i = 0; i < gpu->queue_count; i++) {
         app_gpu_dump_queue_props(gpu, i);
         printf("\n");
@@ -1099,8 +1364,7 @@
     // make the console window bigger
     CONSOLE_SCREEN_BUFFER_INFO csbi;
     COORD bufferSize;
-    if (GetConsoleScreenBufferInfo(consoleHandle, &csbi))
-    {
+    if (GetConsoleScreenBufferInfo(consoleHandle, &csbi)) {
         bufferSize.X = csbi.dwSize.X + 30;
         bufferSize.Y = 20000;
         SetConsoleScreenBufferSize(consoleHandle, bufferSize);
@@ -1141,33 +1405,11 @@
 
     app_create_instance(&inst);
 
-    printf("Instance Extensions and layers:\n");
-    printf("===============================\n");
+    printf("\nInstance Extensions:\n");
+    printf("====================\n");
     app_dump_extensions("", "Instance", inst.global_extension_count,
                         inst.global_extensions);
 
-    printf("Instance Layers\tcount = %d\n", inst.global_layer_count);
-    for (uint32_t i = 0; i < inst.global_layer_count; i++) {
-        uint32_t major, minor, patch;
-        char spec_version[64], layer_version[64];
-        VkLayerProperties const *layer_prop =
-            &inst.global_layers[i].layer_properties;
-
-        extract_version(layer_prop->specVersion, &major, &minor, &patch);
-        snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor,
-                 patch);
-        snprintf(layer_version, sizeof(layer_version), "%d",
-                 layer_prop->implementationVersion);
-        printf("\t%s (%s) Vulkan version %s, layer version %s\n",
-               layer_prop->layerName, (char *)layer_prop->description,
-               spec_version, layer_version);
-
-        app_dump_extensions("\t",
-                            inst.global_layers[i].layer_properties.layerName,
-                            inst.global_layers[i].extension_count,
-                            inst.global_layers[i].extension_properties);
-    }
-
     err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL);
     if (err)
         ERR_EXIT(err);
@@ -1181,6 +1423,104 @@
 
     for (i = 0; i < gpu_count; i++) {
         app_gpu_init(&gpus[i], i, objs[i]);
+        printf("\n\n");
+    }
+
+    //---Layer-Device-Extensions---
+    printf("Layers: count = %d\n", inst.global_layer_count);
+    printf("=======\n");
+    for (uint32_t i = 0; i < inst.global_layer_count; i++) {
+        uint32_t major, minor, patch;
+        char spec_version[64], layer_version[64];
+        VkLayerProperties const *layer_prop =
+            &inst.global_layers[i].layer_properties;
+
+        extract_version(layer_prop->specVersion, &major, &minor, &patch);
+        snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor,
+                 patch);
+        snprintf(layer_version, sizeof(layer_version), "%d",
+                 layer_prop->implementationVersion);
+        printf("%s (%s) Vulkan version %s, layer version %s\n",
+               layer_prop->layerName, (char *)layer_prop->description,
+               spec_version, layer_version);
+
+        app_dump_extensions("\t", "Layer",
+                            inst.global_layers[i].extension_count,
+                            inst.global_layers[i].extension_properties);
+
+        char *layerName = inst.global_layers[i].layer_properties.layerName;
+        printf("\tDevices \tcount = %d\n", gpu_count);
+        for (uint32_t j = 0; j < gpu_count; j++) {
+            printf("\t\tGPU id       : %u (%s)\n", j, gpus[j].props.deviceName);
+            uint32_t count = 0;
+            VkExtensionProperties *props;
+            app_get_physical_device_layer_extensions(&gpus[j], layerName,
+                                                     &count, &props);
+            app_dump_extensions("\t\t", "Layer-Device", count, props);
+            free(props);
+        }
+        printf("\n");
+    }
+    fflush(stdout);
+    //-----------------------------
+
+    printf("Presentable Surface formats:\n");
+    printf("============================\n");
+    inst.width = 256;
+    inst.height = 256;
+    int formatCount = 0;
+
+//--WIN32--
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    if (has_extension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
+                      inst.global_extension_count, inst.global_extensions)) {
+        app_create_win32_window(&inst);
+        for (i = 0; i < gpu_count; i++) {
+            app_create_win32_surface(&inst);
+            printf("GPU id       : %u (%s)\n", i, gpus[i].props.deviceName);
+            printf("Surface type : %s\n", VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
+            formatCount += app_dump_surface_formats(&inst, &gpus[i]);
+            app_destroy_surface(&inst);
+        }
+        app_destroy_win32_window(&inst);
+    }
+#endif
+//--XCB--
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    if (has_extension(VK_KHR_XCB_SURFACE_EXTENSION_NAME,
+                      inst.global_extension_count, inst.global_extensions)) {
+        app_create_xcb_window(&inst);
+        for (i = 0; i < gpu_count; i++) {
+            app_create_xcb_surface(&inst);
+            printf("GPU id       : %u (%s)\n", i, gpus[i].props.deviceName);
+            printf("Surface type : %s\n", VK_KHR_XCB_SURFACE_EXTENSION_NAME);
+            formatCount += app_dump_surface_formats(&inst, &gpus[i]);
+            app_destroy_surface(&inst);
+        }
+        app_destroy_xcb_window(&inst);
+    }
+#endif
+//--XLIB--
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    if (has_extension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
+                      inst.global_extension_count, inst.global_extensions)) {
+        app_create_xlib_window(&inst);
+        for (i = 0; i < gpu_count; i++) {
+            app_create_xlib_surface(&inst);
+            printf("GPU id       : %u (%s)\n", i, gpus[i].props.deviceName);
+            printf("Surface type : %s\n", VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
+            formatCount += app_dump_surface_formats(&inst, &gpus[i]);
+            app_destroy_surface(&inst);
+        }
+        app_destroy_xlib_window(&inst);
+    }
+#endif
+    // TODO: Android / Wayland / MIR
+    if (!formatCount)
+        printf("None found\n");
+    //---------
+
+    for (i = 0; i < gpu_count; i++) {
         app_gpu_dump(&gpus[i]);
         printf("\n\n");
     }
diff --git a/determine_vs_version.py b/determine_vs_version.py
old mode 100644
new mode 100755
diff --git a/generator.py b/generator.py
old mode 100644
new mode 100755
index e9aa8d4..65c6a40
--- a/generator.py
+++ b/generator.py
@@ -2573,9 +2573,9 @@
                                 limit = element[0:element.find('s[]')] + 'Count'
                                 dotp = limit.rfind('.p')
                                 limit = limit[0:dotp+1] + limit[dotp+2:dotp+3].lower() + limit[dotp+3:]
-                                paramdecl += '        for(uint32_t index2=0;index2<'+limit+';index2++)'
+                                paramdecl += '        for(uint32_t index2=0;index2<'+limit+';index2++)\n'
                                 element = element.replace('[]','[index2]')
-                            paramdecl += '        ' + functionprefix + 'WriteObject(my_data, ' + element + ');\n'
+                            paramdecl += '            ' + functionprefix + 'WriteObject(my_data, ' + element + ');\n'
                         paramdecl += '    }\n'
                     else:
                         # externsync can list members to synchronize
@@ -2601,7 +2601,7 @@
             for param in explicitexternsyncparams:
                 externsyncattrib = param.attrib.get('externsync')
                 paramname = param.find('name')
-                paramdecl += '// Host access to '
+                paramdecl += '    // Host access to '
                 if externsyncattrib == 'true':
                     if self.paramIsArray(param):
                         paramdecl += 'each member of ' + paramname.text
@@ -2810,12 +2810,19 @@
         else:
             assignresult = ''
 
-        self.appendSection('command', str(startthreadsafety))
+        self.appendSection('command', '    bool threadChecks = startMultiThread();')
+        self.appendSection('command', '    if (threadChecks) {')
+        self.appendSection('command', "    "+"\n    ".join(str(startthreadsafety).rstrip().split("\n")))
+        self.appendSection('command', '    }')
         params = cmdinfo.elem.findall('param/name')
         paramstext = ','.join([str(param.text) for param in params])
         API = cmdinfo.elem.attrib.get('name').replace('vk','pTable->',1)
         self.appendSection('command', '    ' + assignresult + API + '(' + paramstext + ');')
-        self.appendSection('command', str(finishthreadsafety))
+        self.appendSection('command', '    if (threadChecks) {')
+        self.appendSection('command', "    "+"\n    ".join(str(finishthreadsafety).rstrip().split("\n")))
+        self.appendSection('command', '    } else {')
+        self.appendSection('command', '        finishMultiThread();')
+        self.appendSection('command', '    }')
         # Return result variable, if any.
         if (resulttype != None):
             self.appendSection('command', '    return result;')
@@ -2863,6 +2870,8 @@
             'vkDebugReportMessageEXT']
         # Validation conditions for some special case struct members that are conditionally validated
         self.structMemberValidationConditions = { 'VkPipelineColorBlendStateCreateInfo' : { 'logicOp' : '{}logicOpEnable == VK_TRUE' } }
+        # Header version
+        self.headerVersion = None
         # Internal state - accumulators for different inner block text
         self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
         self.structNames = []                             # List of Vulkan struct typenames
@@ -2944,6 +2953,7 @@
         # Accumulate includes, defines, types, enums, function pointer typedefs,
         # end function prototypes separately for this feature. They're only
         # printed in endFeature().
+        self.headerVersion = None
         self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
         self.structNames = []
         self.stypes = []
@@ -2969,6 +2979,10 @@
             self.processStructMemberData()
             # Generate the command parameter checking code from the captured data
             self.processCmdData()
+            # Write the declaration for the HeaderVersion
+            if self.headerVersion:
+                write('const uint32_t GeneratedHeaderVersion = {};'.format(self.headerVersion), file=self.outFile)
+                self.newline()
             # Write the declarations for the VkFlags values combining all flag bits
             for flag in sorted(self.flags):
                 flagBits = flag.replace('Flags', 'FlagBits')
@@ -3012,6 +3026,10 @@
             self.handleTypes.add(name)
         elif (category == 'bitmask'):
             self.flags.add(name)
+        elif (category == 'define'):
+            if name == 'VK_HEADER_VERSION':
+                nameElem = typeElem.find('name')
+                self.headerVersion = noneStr(nameElem.tail).strip()
     #
     # Struct parameter check generation.
     # This is a special case of the <type> tag where the contents are
@@ -3413,7 +3431,7 @@
             extStructCount = 'ARRAY_SIZE(allowedStructs)'
             extStructVar = 'allowedStructs'
             extStructNames = '"' + ', '.join(structs) + '"'
-        checkExpr.append('skipCall |= validate_struct_pnext(report_data, "{}", "{}", {}, {}{}, {}, {});\n'.format(
+        checkExpr.append('skipCall |= validate_struct_pnext(report_data, "{}", "{}", {}, {}{}, {}, {}, GeneratedHeaderVersion);\n'.format(
             funcPrintName, valuePrintName, extStructNames, prefix, value.name, extStructCount, extStructVar))
         return checkExpr
     #
@@ -3566,10 +3584,10 @@
                             usedLines += self.makeStructNextCheck(valuePrefix, value, funcName, valueDisplayName)
                     else:
                         usedLines += self.makePointerCheck(valuePrefix, value, lenParam, req, cvReq, cpReq, funcName, lenDisplayName, valueDisplayName)
-                #
-                # If this is a pointer to a struct (input), see if it contains members that need to be checked
-                if value.type in self.validatedStructs and value.isconst:
-                    usedLines.append(self.expandStructPointerCode(valuePrefix, value, lenParam, funcName, valueDisplayName))
+                    #
+                    # If this is a pointer to a struct (input), see if it contains members that need to be checked
+                    if value.type in self.validatedStructs and value.isconst:
+                        usedLines.append(self.expandStructPointerCode(valuePrefix, value, lenParam, funcName, valueDisplayName))
             # Non-pointer types
             else:
                 #
@@ -3600,12 +3618,12 @@
                     elif value.israngedenum:
                         enumRange = self.enumRanges[value.type]
                         usedLines.append('skipCall |= validate_ranged_enum(report_data, "{}", "{}", "{}", {}, {}, {}{});\n'.format(funcName, valueDisplayName, value.type, enumRange[0], enumRange[1], valuePrefix, value.name))
-                #
-                # If this is a pointer to a struct (input), see if it contains members that need to be checked
-                if value.type in self.validatedStructs:
-                    memberNamePrefix = '{}{}.'.format(valuePrefix, value.name)
-                    memberDisplayNamePrefix = '{}.'.format(valueDisplayName)
-                    usedLines.append(self.expandStructCode(self.validatedStructs[value.type], funcName, memberNamePrefix, memberDisplayNamePrefix, '', []))
+                    #
+                    # If this is a struct, see if it contains members that need to be checked
+                    if value.type in self.validatedStructs:
+                        memberNamePrefix = '{}{}.'.format(valuePrefix, value.name)
+                        memberDisplayNamePrefix = '{}.'.format(valueDisplayName)
+                        usedLines.append(self.expandStructCode(self.validatedStructs[value.type], funcName, memberNamePrefix, memberDisplayNamePrefix, '', []))
             #
             # Append the parameter check to the function body for the current command
             if usedLines:
diff --git a/glslang_revert_a5c33d.patch.txt b/glslang_revert_a5c33d.patch.txt
new file mode 100644
index 0000000..0d7075c
--- /dev/null
+++ b/glslang_revert_a5c33d.patch.txt
@@ -0,0 +1,18 @@
+diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
+index dd11304..aebc986 100755
+--- a/SPIRV/GlslangToSpv.cpp
++++ b/SPIRV/GlslangToSpv.cpp
+@@ -2630,13 +2630,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
+             bias = true;
+     }
+ 
+-    // See if the sampler param should really be just the SPV image part
+-    if (cracked.fetch) {
+-        // a fetch needs to have the image extracted first
+-        if (builder.isSampledImage(params.sampler))
+-            params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
+-    }
+-
+     // set the rest of the arguments
+ 
+     params.coords = arguments[1];
diff --git a/glslang_revision b/glslang_revision
index ac7412c..9a03f5a 100644
--- a/glslang_revision
+++ b/glslang_revision
@@ -1 +1 @@
-4678ca9dacfec7a084dbc69bbe568bdad6889f1b
+e4821e43c86d97bcf65fb07c1f70471b7102978d
diff --git a/include/vulkan/vk_layer.h b/include/vulkan/vk_layer.h
index cf16b2b..8b7d82f 100644
--- a/include/vulkan/vk_layer.h
+++ b/include/vulkan/vk_layer.h
@@ -234,23 +234,6 @@
         CreateDisplayPlaneSurfaceKHR;
 } VkLayerInstanceDispatchTable;
 
-// LL node for tree of dbg callback functions
-typedef struct VkLayerDbgFunctionNode_ {
-    VkDebugReportCallbackEXT msgCallback;
-    PFN_vkDebugReportCallbackEXT pfnMsgCallback;
-    VkFlags msgFlags;
-    void *pUserData;
-    struct VkLayerDbgFunctionNode_ *pNext;
-} VkLayerDbgFunctionNode;
-
-typedef enum VkLayerDbgAction_ {
-    VK_DBG_LAYER_ACTION_IGNORE = 0x0,
-    VK_DBG_LAYER_ACTION_CALLBACK = 0x1,
-    VK_DBG_LAYER_ACTION_LOG_MSG = 0x2,
-    VK_DBG_LAYER_ACTION_BREAK = 0x4,
-    VK_DBG_LAYER_ACTION_DEBUG_OUTPUT = 0x8,
-} VkLayerDbgAction;
-
 // ------------------------------------------------------------------------------------------------
 // CreateInstance and CreateDevice support structures
 
diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h
index 2f18076..34de809 100644
--- a/include/vulkan/vulkan.h
+++ b/include/vulkan/vulkan.h
@@ -43,7 +43,7 @@
 #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
 #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
 // Version of this file
-#define VK_HEADER_VERSION 13
+#define VK_HEADER_VERSION 21
 
 
 #define VK_NULL_HANDLE 0
@@ -214,6 +214,9 @@
     VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000,
     VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001,
     VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002,
+    VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
+    VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
+    VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
     VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
     VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
     VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
@@ -2347,7 +2350,7 @@
 typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter);
 typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions);
 typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions);
-typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t* pData);
+typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData);
 typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data);
 typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
 typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
@@ -3032,7 +3035,7 @@
     VkBuffer                                    dstBuffer,
     VkDeviceSize                                dstOffset,
     VkDeviceSize                                dataSize,
-    const uint32_t*                             pData);
+    const void*                                 pData);
 
 VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(
     VkCommandBuffer                             commandBuffer,
@@ -3715,7 +3718,7 @@
 #define VK_EXT_debug_report 1
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
 
-#define VK_EXT_DEBUG_REPORT_SPEC_VERSION  2
+#define VK_EXT_DEBUG_REPORT_SPEC_VERSION  3
 #define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report"
 #define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT
 
@@ -3855,6 +3858,16 @@
 
 
 
+#define VK_AMD_shader_trinary_minmax 1
+#define VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION 1
+#define VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME "VK_AMD_shader_trinary_minmax"
+
+
+#define VK_AMD_shader_explicit_vertex_parameter 1
+#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION 1
+#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME "VK_AMD_shader_explicit_vertex_parameter"
+
+
 #define VK_EXT_debug_marker 1
 #define VK_EXT_DEBUG_MARKER_SPEC_VERSION  3
 #define VK_EXT_DEBUG_MARKER_EXTENSION_NAME "VK_EXT_debug_marker"
@@ -3912,6 +3925,36 @@
     VkDebugMarkerMarkerInfoEXT*                 pMarkerInfo);
 #endif
 
+#define VK_AMD_gcn_shader 1
+#define VK_AMD_GCN_SHADER_SPEC_VERSION    1
+#define VK_AMD_GCN_SHADER_EXTENSION_NAME  "VK_AMD_gcn_shader"
+
+
+#define VK_NV_dedicated_allocation 1
+#define VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION 1
+#define VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_NV_dedicated_allocation"
+
+typedef struct VkDedicatedAllocationImageCreateInfoNV {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBool32           dedicatedAllocation;
+} VkDedicatedAllocationImageCreateInfoNV;
+
+typedef struct VkDedicatedAllocationBufferCreateInfoNV {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBool32           dedicatedAllocation;
+} VkDedicatedAllocationBufferCreateInfoNV;
+
+typedef struct VkDedicatedAllocationMemoryAllocateInfoNV {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkImage            image;
+    VkBuffer           buffer;
+} VkDedicatedAllocationMemoryAllocateInfoNV;
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/vulkan/vulkan.hpp b/include/vulkan/vulkan.hpp
new file mode 100644
index 0000000..fcabd18
--- /dev/null
+++ b/include/vulkan/vulkan.hpp
@@ -0,0 +1,19340 @@
+// Copyright (c) 2015-2016 The Khronos Group Inc.
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and/or associated documentation files (the
+// "Materials"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are 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 Materials.
+// 
+// THE MATERIALS ARE 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
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+// This header is generated from the Khronos Vulkan XML API Registry.
+
+
+#ifndef VULKAN_HPP
+#define VULKAN_HPP
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <initializer_list>
+#include <string>
+#include <system_error>
+#include <type_traits>
+#include <vulkan/vulkan.h>
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+# include <memory>
+# include <vector>
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+static_assert( VK_HEADER_VERSION ==  21 , "Wrong VK_HEADER_VERSION!" );
+
+// 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default.
+// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION
+#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+#define VULKAN_HPP_TYPESAFE_CONVERSION 1
+#endif
+
+#if !defined(VULKAN_HPP_HAS_UNRESTRICTED_UNIONS)
+# if defined(__clang__)
+#  if __has_feature(cxx_unrestricted_unions)
+#   define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
+#  endif
+# elif defined(__GNUC__)
+#  define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#  if 40600 <= GCC_VERSION
+#   define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
+#  endif
+# elif defined(_MSC_VER)
+#  if 1900 <= _MSC_VER
+#   define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
+#  endif
+# endif
+#endif
+
+namespace vk
+{
+  template <typename BitType, typename MaskType = VkFlags>
+  class Flags
+  {
+  public:
+    Flags()
+      : m_mask(0)
+    {
+    }
+
+    Flags(BitType bit)
+      : m_mask(static_cast<MaskType>(bit))
+    {
+    }
+
+    Flags(Flags<BitType> const& rhs)
+      : m_mask(rhs.m_mask)
+    {
+    }
+
+    Flags<BitType> & operator=(Flags<BitType> const& rhs)
+    {
+      m_mask = rhs.m_mask;
+      return *this;
+    }
+
+    Flags<BitType> & operator|=(Flags<BitType> const& rhs)
+    {
+      m_mask |= rhs.m_mask;
+      return *this;
+    }
+
+    Flags<BitType> & operator&=(Flags<BitType> const& rhs)
+    {
+      m_mask &= rhs.m_mask;
+      return *this;
+    }
+
+    Flags<BitType> & operator^=(Flags<BitType> const& rhs)
+    {
+      m_mask ^= rhs.m_mask;
+      return *this;
+    }
+
+    Flags<BitType> operator|(Flags<BitType> const& rhs) const
+    {
+      Flags<BitType> result(*this);
+      result |= rhs;
+      return result;
+    }
+
+    Flags<BitType> operator&(Flags<BitType> const& rhs) const
+    {
+      Flags<BitType> result(*this);
+      result &= rhs;
+      return result;
+    }
+
+    Flags<BitType> operator^(Flags<BitType> const& rhs) const
+    {
+      Flags<BitType> result(*this);
+      result ^= rhs;
+      return result;
+    }
+
+    bool operator!() const
+    {
+      return !m_mask;
+    }
+
+    bool operator==(Flags<BitType> const& rhs) const
+    {
+      return m_mask == rhs.m_mask;
+    }
+
+    bool operator!=(Flags<BitType> const& rhs) const
+    {
+      return m_mask != rhs.m_mask;
+    }
+
+    explicit operator bool() const
+    {
+      return !!m_mask;
+    }
+
+    explicit operator MaskType() const
+    {
+        return m_mask;
+    }
+
+  private:
+    MaskType  m_mask;
+  };
+  
+  template <typename BitType>
+  Flags<BitType> operator|(BitType bit, Flags<BitType> const& flags)
+  {
+    return flags | bit;
+  }
+  
+  template <typename BitType>
+  Flags<BitType> operator&(BitType bit, Flags<BitType> const& flags)
+  {
+    return flags & bit;
+  }
+  
+  template <typename BitType>
+  Flags<BitType> operator^(BitType bit, Flags<BitType> const& flags)
+  {
+    return flags ^ bit;
+  }
+
+  template <typename RefType>
+  class Optional
+  {
+  public:
+    Optional(RefType & reference) { m_ptr = &reference; }
+    Optional(std::nullptr_t) { m_ptr = nullptr; }
+
+    operator RefType*() const { return m_ptr; }
+    RefType const* operator->() const { return m_ptr; }
+    explicit operator bool() const { return !!m_ptr; }
+
+  private:
+    RefType *m_ptr;
+  };
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+  template <typename T>
+  class ArrayProxy
+  {
+  public:
+    ArrayProxy(std::nullptr_t)
+      : m_count(0)
+      , m_ptr(nullptr)
+    {}
+
+    ArrayProxy(T & ptr)
+      : m_count(1)
+      , m_ptr(&ptr)
+    {}
+
+    ArrayProxy(uint32_t count, T * ptr)
+      : m_count(count)
+      , m_ptr(ptr)
+    {}
+
+    template <size_t N>
+    ArrayProxy(std::array<typename std::remove_const<T>::type, N> & data)
+      : m_count(N)
+      , m_ptr(data.data())
+    {}
+
+    template <size_t N>
+    ArrayProxy(std::array<typename std::remove_const<T>::type, N> const& data)
+      : m_count(N)
+      , m_ptr(data.data())
+    {}
+
+    template <class Allocator = std::allocator<typename std::remove_const<T>::type>>
+    ArrayProxy(std::vector<typename std::remove_const<T>::type, Allocator> & data)
+      : m_count(static_cast<uint32_t>(data.size()))
+      , m_ptr(data.data())
+    {}
+
+    template <class Allocator = std::allocator<typename std::remove_const<T>::type>>
+    ArrayProxy(std::vector<typename std::remove_const<T>::type, Allocator> const& data)
+      : m_count(static_cast<uint32_t>(data.size()))
+      , m_ptr(data.data())
+    {}
+
+    ArrayProxy(std::initializer_list<T> const& data)
+      : m_count(static_cast<uint32_t>(data.end() - data.begin()))
+      , m_ptr(data.begin())
+    {}
+
+    const T * begin() const
+    {
+      return m_ptr;
+    }
+
+    const T * end() const
+    {
+      return m_ptr + m_count;
+    }
+
+    const T & front() const
+    {
+      assert(m_count && m_ptr);
+      return *m_ptr;
+    }
+
+    const T & back() const
+    {
+      assert(m_count && m_ptr);
+      return *(m_ptr + m_count - 1);
+    }
+
+    bool empty() const
+    {
+      return (m_count == 0);
+    }
+
+    uint32_t size() const
+    {
+      return m_count;
+    }
+
+    T * data() const
+    {
+      return m_ptr;
+    }
+
+  private:
+    uint32_t  m_count;
+    T *       m_ptr;
+  };
+#endif
+
+  enum class Result
+  {
+    eSuccess = VK_SUCCESS,
+    eNotReady = VK_NOT_READY,
+    eTimeout = VK_TIMEOUT,
+    eEventSet = VK_EVENT_SET,
+    eEventReset = VK_EVENT_RESET,
+    eIncomplete = VK_INCOMPLETE,
+    eErrorOutOfHostMemory = VK_ERROR_OUT_OF_HOST_MEMORY,
+    eErrorOutOfDeviceMemory = VK_ERROR_OUT_OF_DEVICE_MEMORY,
+    eErrorInitializationFailed = VK_ERROR_INITIALIZATION_FAILED,
+    eErrorDeviceLost = VK_ERROR_DEVICE_LOST,
+    eErrorMemoryMapFailed = VK_ERROR_MEMORY_MAP_FAILED,
+    eErrorLayerNotPresent = VK_ERROR_LAYER_NOT_PRESENT,
+    eErrorExtensionNotPresent = VK_ERROR_EXTENSION_NOT_PRESENT,
+    eErrorFeatureNotPresent = VK_ERROR_FEATURE_NOT_PRESENT,
+    eErrorIncompatibleDriver = VK_ERROR_INCOMPATIBLE_DRIVER,
+    eErrorTooManyObjects = VK_ERROR_TOO_MANY_OBJECTS,
+    eErrorFormatNotSupported = VK_ERROR_FORMAT_NOT_SUPPORTED,
+    eErrorSurfaceLostKHR = VK_ERROR_SURFACE_LOST_KHR,
+    eErrorNativeWindowInUseKHR = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR,
+    eSuboptimalKHR = VK_SUBOPTIMAL_KHR,
+    eErrorOutOfDateKHR = VK_ERROR_OUT_OF_DATE_KHR,
+    eErrorIncompatibleDisplayKHR = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR,
+    eErrorValidationFailedEXT = VK_ERROR_VALIDATION_FAILED_EXT,
+    eErrorInvalidShaderNV = VK_ERROR_INVALID_SHADER_NV
+  };
+
+  inline std::string to_string(Result value)
+  {
+    switch (value)
+    {
+    case Result::eSuccess: return "Success";
+    case Result::eNotReady: return "NotReady";
+    case Result::eTimeout: return "Timeout";
+    case Result::eEventSet: return "EventSet";
+    case Result::eEventReset: return "EventReset";
+    case Result::eIncomplete: return "Incomplete";
+    case Result::eErrorOutOfHostMemory: return "ErrorOutOfHostMemory";
+    case Result::eErrorOutOfDeviceMemory: return "ErrorOutOfDeviceMemory";
+    case Result::eErrorInitializationFailed: return "ErrorInitializationFailed";
+    case Result::eErrorDeviceLost: return "ErrorDeviceLost";
+    case Result::eErrorMemoryMapFailed: return "ErrorMemoryMapFailed";
+    case Result::eErrorLayerNotPresent: return "ErrorLayerNotPresent";
+    case Result::eErrorExtensionNotPresent: return "ErrorExtensionNotPresent";
+    case Result::eErrorFeatureNotPresent: return "ErrorFeatureNotPresent";
+    case Result::eErrorIncompatibleDriver: return "ErrorIncompatibleDriver";
+    case Result::eErrorTooManyObjects: return "ErrorTooManyObjects";
+    case Result::eErrorFormatNotSupported: return "ErrorFormatNotSupported";
+    case Result::eErrorSurfaceLostKHR: return "ErrorSurfaceLostKHR";
+    case Result::eErrorNativeWindowInUseKHR: return "ErrorNativeWindowInUseKHR";
+    case Result::eSuboptimalKHR: return "SuboptimalKHR";
+    case Result::eErrorOutOfDateKHR: return "ErrorOutOfDateKHR";
+    case Result::eErrorIncompatibleDisplayKHR: return "ErrorIncompatibleDisplayKHR";
+    case Result::eErrorValidationFailedEXT: return "ErrorValidationFailedEXT";
+    case Result::eErrorInvalidShaderNV: return "ErrorInvalidShaderNV";
+    default: return "invalid";
+    }
+  }
+
+#if defined(_MSC_VER) && (_MSC_VER == 1800)
+# define noexcept _NOEXCEPT
+#endif
+
+  class ErrorCategoryImpl : public std::error_category
+  {
+    public:
+    virtual const char* name() const noexcept override { return "vk::Result"; }
+    virtual std::string message(int ev) const override { return to_string(static_cast<Result>(ev)); }
+  };
+
+#if defined(_MSC_VER) && (_MSC_VER == 1800)
+# undef noexcept
+#endif
+
+  inline const std::error_category& errorCategory()
+  {
+    static ErrorCategoryImpl instance;
+    return instance;
+  }
+
+  inline std::error_code make_error_code(Result e)
+  {
+    return std::error_code(static_cast<int>(e), errorCategory());
+  }
+
+  inline std::error_condition make_error_condition(Result e)
+  {
+    return std::error_condition(static_cast<int>(e), errorCategory());
+  }
+
+} // namespace vk
+
+namespace std
+{
+  template <>
+  struct is_error_code_enum<vk::Result> : public true_type
+  {};
+}
+
+namespace vk
+{
+  template <typename T>
+  struct ResultValue
+  {
+    ResultValue( Result r, T & v )
+      : result( r )
+      , value( v )
+    {}
+
+    Result  result;
+    T       value;
+  };
+
+  template <typename T>
+  struct ResultValueType
+  {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+    typedef ResultValue<T>  type;
+#else
+    typedef T              type;
+#endif
+  };
+
+  template <>  struct ResultValueType<void>
+  {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+    typedef Result type;
+#else
+    typedef void   type;
+#endif
+  };
+
+  inline ResultValueType<void>::type createResultValue( Result result, char const * message )
+  {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+    assert( result == Result::eSuccess );
+    return result;
+#else
+    if ( result != Result::eSuccess )
+    {
+      throw std::system_error( result, message );
+    }
+#endif
+  }
+
+  template <typename T>
+  inline typename ResultValueType<T>::type createResultValue( Result result, T & data, char const * message )
+  {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+    assert( result == Result::eSuccess );
+    return ResultValue<T>( result, data );
+#else
+    if ( result != Result::eSuccess )
+    {
+      throw std::system_error( result, message );
+    }
+    return data;
+#endif
+  }
+
+  inline Result createResultValue( Result result, char const * message, std::initializer_list<Result> successCodes )
+  {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+    assert( std::find( successCodes.begin(), successCodes.end(), result ) != successCodes.end() );
+#else
+    if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() )
+    {
+      throw std::system_error( result, message );
+    }
+#endif
+    return result;
+  }
+
+  template <typename T>
+  inline ResultValue<T> createResultValue( Result result, T & data, char const * message, std::initializer_list<Result> successCodes )
+  {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+    assert( std::find( successCodes.begin(), successCodes.end(), result ) != successCodes.end() );
+#else
+    if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() )
+    {
+      throw std::system_error( result, message );
+    }
+#endif
+    return ResultValue<T>( result, data );
+  }
+
+  using SampleMask = uint32_t;
+
+  using Bool32 = uint32_t;
+
+  using DeviceSize = uint64_t;
+
+  enum class FramebufferCreateFlagBits
+  {
+  };
+
+  using FramebufferCreateFlags = Flags<FramebufferCreateFlagBits, VkFramebufferCreateFlags>;
+
+  inline FramebufferCreateFlags operator|( FramebufferCreateFlagBits bit0, FramebufferCreateFlagBits bit1 )
+  {
+    return FramebufferCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class QueryPoolCreateFlagBits
+  {
+  };
+
+  using QueryPoolCreateFlags = Flags<QueryPoolCreateFlagBits, VkQueryPoolCreateFlags>;
+
+  inline QueryPoolCreateFlags operator|( QueryPoolCreateFlagBits bit0, QueryPoolCreateFlagBits bit1 )
+  {
+    return QueryPoolCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class RenderPassCreateFlagBits
+  {
+  };
+
+  using RenderPassCreateFlags = Flags<RenderPassCreateFlagBits, VkRenderPassCreateFlags>;
+
+  inline RenderPassCreateFlags operator|( RenderPassCreateFlagBits bit0, RenderPassCreateFlagBits bit1 )
+  {
+    return RenderPassCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class SamplerCreateFlagBits
+  {
+  };
+
+  using SamplerCreateFlags = Flags<SamplerCreateFlagBits, VkSamplerCreateFlags>;
+
+  inline SamplerCreateFlags operator|( SamplerCreateFlagBits bit0, SamplerCreateFlagBits bit1 )
+  {
+    return SamplerCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineLayoutCreateFlagBits
+  {
+  };
+
+  using PipelineLayoutCreateFlags = Flags<PipelineLayoutCreateFlagBits, VkPipelineLayoutCreateFlags>;
+
+  inline PipelineLayoutCreateFlags operator|( PipelineLayoutCreateFlagBits bit0, PipelineLayoutCreateFlagBits bit1 )
+  {
+    return PipelineLayoutCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineCacheCreateFlagBits
+  {
+  };
+
+  using PipelineCacheCreateFlags = Flags<PipelineCacheCreateFlagBits, VkPipelineCacheCreateFlags>;
+
+  inline PipelineCacheCreateFlags operator|( PipelineCacheCreateFlagBits bit0, PipelineCacheCreateFlagBits bit1 )
+  {
+    return PipelineCacheCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineDepthStencilStateCreateFlagBits
+  {
+  };
+
+  using PipelineDepthStencilStateCreateFlags = Flags<PipelineDepthStencilStateCreateFlagBits, VkPipelineDepthStencilStateCreateFlags>;
+
+  inline PipelineDepthStencilStateCreateFlags operator|( PipelineDepthStencilStateCreateFlagBits bit0, PipelineDepthStencilStateCreateFlagBits bit1 )
+  {
+    return PipelineDepthStencilStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineDynamicStateCreateFlagBits
+  {
+  };
+
+  using PipelineDynamicStateCreateFlags = Flags<PipelineDynamicStateCreateFlagBits, VkPipelineDynamicStateCreateFlags>;
+
+  inline PipelineDynamicStateCreateFlags operator|( PipelineDynamicStateCreateFlagBits bit0, PipelineDynamicStateCreateFlagBits bit1 )
+  {
+    return PipelineDynamicStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineColorBlendStateCreateFlagBits
+  {
+  };
+
+  using PipelineColorBlendStateCreateFlags = Flags<PipelineColorBlendStateCreateFlagBits, VkPipelineColorBlendStateCreateFlags>;
+
+  inline PipelineColorBlendStateCreateFlags operator|( PipelineColorBlendStateCreateFlagBits bit0, PipelineColorBlendStateCreateFlagBits bit1 )
+  {
+    return PipelineColorBlendStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineMultisampleStateCreateFlagBits
+  {
+  };
+
+  using PipelineMultisampleStateCreateFlags = Flags<PipelineMultisampleStateCreateFlagBits, VkPipelineMultisampleStateCreateFlags>;
+
+  inline PipelineMultisampleStateCreateFlags operator|( PipelineMultisampleStateCreateFlagBits bit0, PipelineMultisampleStateCreateFlagBits bit1 )
+  {
+    return PipelineMultisampleStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineRasterizationStateCreateFlagBits
+  {
+  };
+
+  using PipelineRasterizationStateCreateFlags = Flags<PipelineRasterizationStateCreateFlagBits, VkPipelineRasterizationStateCreateFlags>;
+
+  inline PipelineRasterizationStateCreateFlags operator|( PipelineRasterizationStateCreateFlagBits bit0, PipelineRasterizationStateCreateFlagBits bit1 )
+  {
+    return PipelineRasterizationStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineViewportStateCreateFlagBits
+  {
+  };
+
+  using PipelineViewportStateCreateFlags = Flags<PipelineViewportStateCreateFlagBits, VkPipelineViewportStateCreateFlags>;
+
+  inline PipelineViewportStateCreateFlags operator|( PipelineViewportStateCreateFlagBits bit0, PipelineViewportStateCreateFlagBits bit1 )
+  {
+    return PipelineViewportStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineTessellationStateCreateFlagBits
+  {
+  };
+
+  using PipelineTessellationStateCreateFlags = Flags<PipelineTessellationStateCreateFlagBits, VkPipelineTessellationStateCreateFlags>;
+
+  inline PipelineTessellationStateCreateFlags operator|( PipelineTessellationStateCreateFlagBits bit0, PipelineTessellationStateCreateFlagBits bit1 )
+  {
+    return PipelineTessellationStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineInputAssemblyStateCreateFlagBits
+  {
+  };
+
+  using PipelineInputAssemblyStateCreateFlags = Flags<PipelineInputAssemblyStateCreateFlagBits, VkPipelineInputAssemblyStateCreateFlags>;
+
+  inline PipelineInputAssemblyStateCreateFlags operator|( PipelineInputAssemblyStateCreateFlagBits bit0, PipelineInputAssemblyStateCreateFlagBits bit1 )
+  {
+    return PipelineInputAssemblyStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineVertexInputStateCreateFlagBits
+  {
+  };
+
+  using PipelineVertexInputStateCreateFlags = Flags<PipelineVertexInputStateCreateFlagBits, VkPipelineVertexInputStateCreateFlags>;
+
+  inline PipelineVertexInputStateCreateFlags operator|( PipelineVertexInputStateCreateFlagBits bit0, PipelineVertexInputStateCreateFlagBits bit1 )
+  {
+    return PipelineVertexInputStateCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineShaderStageCreateFlagBits
+  {
+  };
+
+  using PipelineShaderStageCreateFlags = Flags<PipelineShaderStageCreateFlagBits, VkPipelineShaderStageCreateFlags>;
+
+  inline PipelineShaderStageCreateFlags operator|( PipelineShaderStageCreateFlagBits bit0, PipelineShaderStageCreateFlagBits bit1 )
+  {
+    return PipelineShaderStageCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class DescriptorSetLayoutCreateFlagBits
+  {
+  };
+
+  using DescriptorSetLayoutCreateFlags = Flags<DescriptorSetLayoutCreateFlagBits, VkDescriptorSetLayoutCreateFlags>;
+
+  inline DescriptorSetLayoutCreateFlags operator|( DescriptorSetLayoutCreateFlagBits bit0, DescriptorSetLayoutCreateFlagBits bit1 )
+  {
+    return DescriptorSetLayoutCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class BufferViewCreateFlagBits
+  {
+  };
+
+  using BufferViewCreateFlags = Flags<BufferViewCreateFlagBits, VkBufferViewCreateFlags>;
+
+  inline BufferViewCreateFlags operator|( BufferViewCreateFlagBits bit0, BufferViewCreateFlagBits bit1 )
+  {
+    return BufferViewCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class InstanceCreateFlagBits
+  {
+  };
+
+  using InstanceCreateFlags = Flags<InstanceCreateFlagBits, VkInstanceCreateFlags>;
+
+  inline InstanceCreateFlags operator|( InstanceCreateFlagBits bit0, InstanceCreateFlagBits bit1 )
+  {
+    return InstanceCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class DeviceCreateFlagBits
+  {
+  };
+
+  using DeviceCreateFlags = Flags<DeviceCreateFlagBits, VkDeviceCreateFlags>;
+
+  inline DeviceCreateFlags operator|( DeviceCreateFlagBits bit0, DeviceCreateFlagBits bit1 )
+  {
+    return DeviceCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class DeviceQueueCreateFlagBits
+  {
+  };
+
+  using DeviceQueueCreateFlags = Flags<DeviceQueueCreateFlagBits, VkDeviceQueueCreateFlags>;
+
+  inline DeviceQueueCreateFlags operator|( DeviceQueueCreateFlagBits bit0, DeviceQueueCreateFlagBits bit1 )
+  {
+    return DeviceQueueCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class ImageViewCreateFlagBits
+  {
+  };
+
+  using ImageViewCreateFlags = Flags<ImageViewCreateFlagBits, VkImageViewCreateFlags>;
+
+  inline ImageViewCreateFlags operator|( ImageViewCreateFlagBits bit0, ImageViewCreateFlagBits bit1 )
+  {
+    return ImageViewCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class SemaphoreCreateFlagBits
+  {
+  };
+
+  using SemaphoreCreateFlags = Flags<SemaphoreCreateFlagBits, VkSemaphoreCreateFlags>;
+
+  inline SemaphoreCreateFlags operator|( SemaphoreCreateFlagBits bit0, SemaphoreCreateFlagBits bit1 )
+  {
+    return SemaphoreCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class ShaderModuleCreateFlagBits
+  {
+  };
+
+  using ShaderModuleCreateFlags = Flags<ShaderModuleCreateFlagBits, VkShaderModuleCreateFlags>;
+
+  inline ShaderModuleCreateFlags operator|( ShaderModuleCreateFlagBits bit0, ShaderModuleCreateFlagBits bit1 )
+  {
+    return ShaderModuleCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class EventCreateFlagBits
+  {
+  };
+
+  using EventCreateFlags = Flags<EventCreateFlagBits, VkEventCreateFlags>;
+
+  inline EventCreateFlags operator|( EventCreateFlagBits bit0, EventCreateFlagBits bit1 )
+  {
+    return EventCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class MemoryMapFlagBits
+  {
+  };
+
+  using MemoryMapFlags = Flags<MemoryMapFlagBits, VkMemoryMapFlags>;
+
+  inline MemoryMapFlags operator|( MemoryMapFlagBits bit0, MemoryMapFlagBits bit1 )
+  {
+    return MemoryMapFlags( bit0 ) | bit1;
+  }
+
+  enum class SubpassDescriptionFlagBits
+  {
+  };
+
+  using SubpassDescriptionFlags = Flags<SubpassDescriptionFlagBits, VkSubpassDescriptionFlags>;
+
+  inline SubpassDescriptionFlags operator|( SubpassDescriptionFlagBits bit0, SubpassDescriptionFlagBits bit1 )
+  {
+    return SubpassDescriptionFlags( bit0 ) | bit1;
+  }
+
+  enum class DescriptorPoolResetFlagBits
+  {
+  };
+
+  using DescriptorPoolResetFlags = Flags<DescriptorPoolResetFlagBits, VkDescriptorPoolResetFlags>;
+
+  inline DescriptorPoolResetFlags operator|( DescriptorPoolResetFlagBits bit0, DescriptorPoolResetFlagBits bit1 )
+  {
+    return DescriptorPoolResetFlags( bit0 ) | bit1;
+  }
+
+  enum class SwapchainCreateFlagBitsKHR
+  {
+  };
+
+  using SwapchainCreateFlagsKHR = Flags<SwapchainCreateFlagBitsKHR, VkSwapchainCreateFlagsKHR>;
+
+  inline SwapchainCreateFlagsKHR operator|( SwapchainCreateFlagBitsKHR bit0, SwapchainCreateFlagBitsKHR bit1 )
+  {
+    return SwapchainCreateFlagsKHR( bit0 ) | bit1;
+  }
+
+  enum class DisplayModeCreateFlagBitsKHR
+  {
+  };
+
+  using DisplayModeCreateFlagsKHR = Flags<DisplayModeCreateFlagBitsKHR, VkDisplayModeCreateFlagsKHR>;
+
+  inline DisplayModeCreateFlagsKHR operator|( DisplayModeCreateFlagBitsKHR bit0, DisplayModeCreateFlagBitsKHR bit1 )
+  {
+    return DisplayModeCreateFlagsKHR( bit0 ) | bit1;
+  }
+
+  enum class DisplaySurfaceCreateFlagBitsKHR
+  {
+  };
+
+  using DisplaySurfaceCreateFlagsKHR = Flags<DisplaySurfaceCreateFlagBitsKHR, VkDisplaySurfaceCreateFlagsKHR>;
+
+  inline DisplaySurfaceCreateFlagsKHR operator|( DisplaySurfaceCreateFlagBitsKHR bit0, DisplaySurfaceCreateFlagBitsKHR bit1 )
+  {
+    return DisplaySurfaceCreateFlagsKHR( bit0 ) | bit1;
+  }
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+  enum class AndroidSurfaceCreateFlagBitsKHR
+  {
+  };
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+  using AndroidSurfaceCreateFlagsKHR = Flags<AndroidSurfaceCreateFlagBitsKHR, VkAndroidSurfaceCreateFlagsKHR>;
+
+  inline AndroidSurfaceCreateFlagsKHR operator|( AndroidSurfaceCreateFlagBitsKHR bit0, AndroidSurfaceCreateFlagBitsKHR bit1 )
+  {
+    return AndroidSurfaceCreateFlagsKHR( bit0 ) | bit1;
+  }
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+  enum class MirSurfaceCreateFlagBitsKHR
+  {
+  };
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+  using MirSurfaceCreateFlagsKHR = Flags<MirSurfaceCreateFlagBitsKHR, VkMirSurfaceCreateFlagsKHR>;
+
+  inline MirSurfaceCreateFlagsKHR operator|( MirSurfaceCreateFlagBitsKHR bit0, MirSurfaceCreateFlagBitsKHR bit1 )
+  {
+    return MirSurfaceCreateFlagsKHR( bit0 ) | bit1;
+  }
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+  enum class WaylandSurfaceCreateFlagBitsKHR
+  {
+  };
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+  using WaylandSurfaceCreateFlagsKHR = Flags<WaylandSurfaceCreateFlagBitsKHR, VkWaylandSurfaceCreateFlagsKHR>;
+
+  inline WaylandSurfaceCreateFlagsKHR operator|( WaylandSurfaceCreateFlagBitsKHR bit0, WaylandSurfaceCreateFlagBitsKHR bit1 )
+  {
+    return WaylandSurfaceCreateFlagsKHR( bit0 ) | bit1;
+  }
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+  enum class Win32SurfaceCreateFlagBitsKHR
+  {
+  };
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+  using Win32SurfaceCreateFlagsKHR = Flags<Win32SurfaceCreateFlagBitsKHR, VkWin32SurfaceCreateFlagsKHR>;
+
+  inline Win32SurfaceCreateFlagsKHR operator|( Win32SurfaceCreateFlagBitsKHR bit0, Win32SurfaceCreateFlagBitsKHR bit1 )
+  {
+    return Win32SurfaceCreateFlagsKHR( bit0 ) | bit1;
+  }
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+  enum class XlibSurfaceCreateFlagBitsKHR
+  {
+  };
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+  using XlibSurfaceCreateFlagsKHR = Flags<XlibSurfaceCreateFlagBitsKHR, VkXlibSurfaceCreateFlagsKHR>;
+
+  inline XlibSurfaceCreateFlagsKHR operator|( XlibSurfaceCreateFlagBitsKHR bit0, XlibSurfaceCreateFlagBitsKHR bit1 )
+  {
+    return XlibSurfaceCreateFlagsKHR( bit0 ) | bit1;
+  }
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+  enum class XcbSurfaceCreateFlagBitsKHR
+  {
+  };
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+  using XcbSurfaceCreateFlagsKHR = Flags<XcbSurfaceCreateFlagBitsKHR, VkXcbSurfaceCreateFlagsKHR>;
+
+  inline XcbSurfaceCreateFlagsKHR operator|( XcbSurfaceCreateFlagBitsKHR bit0, XcbSurfaceCreateFlagBitsKHR bit1 )
+  {
+    return XcbSurfaceCreateFlagsKHR( bit0 ) | bit1;
+  }
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+  class DeviceMemory
+  {
+  public:
+    DeviceMemory()
+      : m_deviceMemory(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    DeviceMemory(VkDeviceMemory deviceMemory)
+       : m_deviceMemory(deviceMemory)
+    {}
+
+    DeviceMemory& operator=(VkDeviceMemory deviceMemory)
+    {
+      m_deviceMemory = deviceMemory;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkDeviceMemory() const
+    {
+      return m_deviceMemory;
+    }
+
+    explicit operator bool() const
+    {
+      return m_deviceMemory != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_deviceMemory == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkDeviceMemory m_deviceMemory;
+  };
+  static_assert( sizeof( DeviceMemory ) == sizeof( VkDeviceMemory ), "handle and wrapper have different size!" );
+
+  class CommandPool
+  {
+  public:
+    CommandPool()
+      : m_commandPool(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    CommandPool(VkCommandPool commandPool)
+       : m_commandPool(commandPool)
+    {}
+
+    CommandPool& operator=(VkCommandPool commandPool)
+    {
+      m_commandPool = commandPool;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkCommandPool() const
+    {
+      return m_commandPool;
+    }
+
+    explicit operator bool() const
+    {
+      return m_commandPool != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_commandPool == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkCommandPool m_commandPool;
+  };
+  static_assert( sizeof( CommandPool ) == sizeof( VkCommandPool ), "handle and wrapper have different size!" );
+
+  class Buffer
+  {
+  public:
+    Buffer()
+      : m_buffer(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Buffer(VkBuffer buffer)
+       : m_buffer(buffer)
+    {}
+
+    Buffer& operator=(VkBuffer buffer)
+    {
+      m_buffer = buffer;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkBuffer() const
+    {
+      return m_buffer;
+    }
+
+    explicit operator bool() const
+    {
+      return m_buffer != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_buffer == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkBuffer m_buffer;
+  };
+  static_assert( sizeof( Buffer ) == sizeof( VkBuffer ), "handle and wrapper have different size!" );
+
+  class BufferView
+  {
+  public:
+    BufferView()
+      : m_bufferView(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    BufferView(VkBufferView bufferView)
+       : m_bufferView(bufferView)
+    {}
+
+    BufferView& operator=(VkBufferView bufferView)
+    {
+      m_bufferView = bufferView;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkBufferView() const
+    {
+      return m_bufferView;
+    }
+
+    explicit operator bool() const
+    {
+      return m_bufferView != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_bufferView == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkBufferView m_bufferView;
+  };
+  static_assert( sizeof( BufferView ) == sizeof( VkBufferView ), "handle and wrapper have different size!" );
+
+  class Image
+  {
+  public:
+    Image()
+      : m_image(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Image(VkImage image)
+       : m_image(image)
+    {}
+
+    Image& operator=(VkImage image)
+    {
+      m_image = image;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkImage() const
+    {
+      return m_image;
+    }
+
+    explicit operator bool() const
+    {
+      return m_image != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_image == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkImage m_image;
+  };
+  static_assert( sizeof( Image ) == sizeof( VkImage ), "handle and wrapper have different size!" );
+
+  class ImageView
+  {
+  public:
+    ImageView()
+      : m_imageView(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    ImageView(VkImageView imageView)
+       : m_imageView(imageView)
+    {}
+
+    ImageView& operator=(VkImageView imageView)
+    {
+      m_imageView = imageView;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkImageView() const
+    {
+      return m_imageView;
+    }
+
+    explicit operator bool() const
+    {
+      return m_imageView != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_imageView == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkImageView m_imageView;
+  };
+  static_assert( sizeof( ImageView ) == sizeof( VkImageView ), "handle and wrapper have different size!" );
+
+  class ShaderModule
+  {
+  public:
+    ShaderModule()
+      : m_shaderModule(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    ShaderModule(VkShaderModule shaderModule)
+       : m_shaderModule(shaderModule)
+    {}
+
+    ShaderModule& operator=(VkShaderModule shaderModule)
+    {
+      m_shaderModule = shaderModule;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkShaderModule() const
+    {
+      return m_shaderModule;
+    }
+
+    explicit operator bool() const
+    {
+      return m_shaderModule != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_shaderModule == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkShaderModule m_shaderModule;
+  };
+  static_assert( sizeof( ShaderModule ) == sizeof( VkShaderModule ), "handle and wrapper have different size!" );
+
+  class Pipeline
+  {
+  public:
+    Pipeline()
+      : m_pipeline(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Pipeline(VkPipeline pipeline)
+       : m_pipeline(pipeline)
+    {}
+
+    Pipeline& operator=(VkPipeline pipeline)
+    {
+      m_pipeline = pipeline;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkPipeline() const
+    {
+      return m_pipeline;
+    }
+
+    explicit operator bool() const
+    {
+      return m_pipeline != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_pipeline == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkPipeline m_pipeline;
+  };
+  static_assert( sizeof( Pipeline ) == sizeof( VkPipeline ), "handle and wrapper have different size!" );
+
+  class PipelineLayout
+  {
+  public:
+    PipelineLayout()
+      : m_pipelineLayout(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    PipelineLayout(VkPipelineLayout pipelineLayout)
+       : m_pipelineLayout(pipelineLayout)
+    {}
+
+    PipelineLayout& operator=(VkPipelineLayout pipelineLayout)
+    {
+      m_pipelineLayout = pipelineLayout;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkPipelineLayout() const
+    {
+      return m_pipelineLayout;
+    }
+
+    explicit operator bool() const
+    {
+      return m_pipelineLayout != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_pipelineLayout == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkPipelineLayout m_pipelineLayout;
+  };
+  static_assert( sizeof( PipelineLayout ) == sizeof( VkPipelineLayout ), "handle and wrapper have different size!" );
+
+  class Sampler
+  {
+  public:
+    Sampler()
+      : m_sampler(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Sampler(VkSampler sampler)
+       : m_sampler(sampler)
+    {}
+
+    Sampler& operator=(VkSampler sampler)
+    {
+      m_sampler = sampler;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkSampler() const
+    {
+      return m_sampler;
+    }
+
+    explicit operator bool() const
+    {
+      return m_sampler != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_sampler == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkSampler m_sampler;
+  };
+  static_assert( sizeof( Sampler ) == sizeof( VkSampler ), "handle and wrapper have different size!" );
+
+  class DescriptorSet
+  {
+  public:
+    DescriptorSet()
+      : m_descriptorSet(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    DescriptorSet(VkDescriptorSet descriptorSet)
+       : m_descriptorSet(descriptorSet)
+    {}
+
+    DescriptorSet& operator=(VkDescriptorSet descriptorSet)
+    {
+      m_descriptorSet = descriptorSet;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkDescriptorSet() const
+    {
+      return m_descriptorSet;
+    }
+
+    explicit operator bool() const
+    {
+      return m_descriptorSet != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_descriptorSet == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkDescriptorSet m_descriptorSet;
+  };
+  static_assert( sizeof( DescriptorSet ) == sizeof( VkDescriptorSet ), "handle and wrapper have different size!" );
+
+  class DescriptorSetLayout
+  {
+  public:
+    DescriptorSetLayout()
+      : m_descriptorSetLayout(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    DescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayout)
+       : m_descriptorSetLayout(descriptorSetLayout)
+    {}
+
+    DescriptorSetLayout& operator=(VkDescriptorSetLayout descriptorSetLayout)
+    {
+      m_descriptorSetLayout = descriptorSetLayout;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkDescriptorSetLayout() const
+    {
+      return m_descriptorSetLayout;
+    }
+
+    explicit operator bool() const
+    {
+      return m_descriptorSetLayout != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_descriptorSetLayout == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkDescriptorSetLayout m_descriptorSetLayout;
+  };
+  static_assert( sizeof( DescriptorSetLayout ) == sizeof( VkDescriptorSetLayout ), "handle and wrapper have different size!" );
+
+  class DescriptorPool
+  {
+  public:
+    DescriptorPool()
+      : m_descriptorPool(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    DescriptorPool(VkDescriptorPool descriptorPool)
+       : m_descriptorPool(descriptorPool)
+    {}
+
+    DescriptorPool& operator=(VkDescriptorPool descriptorPool)
+    {
+      m_descriptorPool = descriptorPool;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkDescriptorPool() const
+    {
+      return m_descriptorPool;
+    }
+
+    explicit operator bool() const
+    {
+      return m_descriptorPool != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_descriptorPool == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkDescriptorPool m_descriptorPool;
+  };
+  static_assert( sizeof( DescriptorPool ) == sizeof( VkDescriptorPool ), "handle and wrapper have different size!" );
+
+  class Fence
+  {
+  public:
+    Fence()
+      : m_fence(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Fence(VkFence fence)
+       : m_fence(fence)
+    {}
+
+    Fence& operator=(VkFence fence)
+    {
+      m_fence = fence;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkFence() const
+    {
+      return m_fence;
+    }
+
+    explicit operator bool() const
+    {
+      return m_fence != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_fence == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkFence m_fence;
+  };
+  static_assert( sizeof( Fence ) == sizeof( VkFence ), "handle and wrapper have different size!" );
+
+  class Semaphore
+  {
+  public:
+    Semaphore()
+      : m_semaphore(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Semaphore(VkSemaphore semaphore)
+       : m_semaphore(semaphore)
+    {}
+
+    Semaphore& operator=(VkSemaphore semaphore)
+    {
+      m_semaphore = semaphore;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkSemaphore() const
+    {
+      return m_semaphore;
+    }
+
+    explicit operator bool() const
+    {
+      return m_semaphore != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_semaphore == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkSemaphore m_semaphore;
+  };
+  static_assert( sizeof( Semaphore ) == sizeof( VkSemaphore ), "handle and wrapper have different size!" );
+
+  class Event
+  {
+  public:
+    Event()
+      : m_event(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Event(VkEvent event)
+       : m_event(event)
+    {}
+
+    Event& operator=(VkEvent event)
+    {
+      m_event = event;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkEvent() const
+    {
+      return m_event;
+    }
+
+    explicit operator bool() const
+    {
+      return m_event != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_event == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkEvent m_event;
+  };
+  static_assert( sizeof( Event ) == sizeof( VkEvent ), "handle and wrapper have different size!" );
+
+  class QueryPool
+  {
+  public:
+    QueryPool()
+      : m_queryPool(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    QueryPool(VkQueryPool queryPool)
+       : m_queryPool(queryPool)
+    {}
+
+    QueryPool& operator=(VkQueryPool queryPool)
+    {
+      m_queryPool = queryPool;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkQueryPool() const
+    {
+      return m_queryPool;
+    }
+
+    explicit operator bool() const
+    {
+      return m_queryPool != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_queryPool == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkQueryPool m_queryPool;
+  };
+  static_assert( sizeof( QueryPool ) == sizeof( VkQueryPool ), "handle and wrapper have different size!" );
+
+  class Framebuffer
+  {
+  public:
+    Framebuffer()
+      : m_framebuffer(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Framebuffer(VkFramebuffer framebuffer)
+       : m_framebuffer(framebuffer)
+    {}
+
+    Framebuffer& operator=(VkFramebuffer framebuffer)
+    {
+      m_framebuffer = framebuffer;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkFramebuffer() const
+    {
+      return m_framebuffer;
+    }
+
+    explicit operator bool() const
+    {
+      return m_framebuffer != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_framebuffer == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkFramebuffer m_framebuffer;
+  };
+  static_assert( sizeof( Framebuffer ) == sizeof( VkFramebuffer ), "handle and wrapper have different size!" );
+
+  class RenderPass
+  {
+  public:
+    RenderPass()
+      : m_renderPass(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    RenderPass(VkRenderPass renderPass)
+       : m_renderPass(renderPass)
+    {}
+
+    RenderPass& operator=(VkRenderPass renderPass)
+    {
+      m_renderPass = renderPass;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkRenderPass() const
+    {
+      return m_renderPass;
+    }
+
+    explicit operator bool() const
+    {
+      return m_renderPass != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_renderPass == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkRenderPass m_renderPass;
+  };
+  static_assert( sizeof( RenderPass ) == sizeof( VkRenderPass ), "handle and wrapper have different size!" );
+
+  class PipelineCache
+  {
+  public:
+    PipelineCache()
+      : m_pipelineCache(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    PipelineCache(VkPipelineCache pipelineCache)
+       : m_pipelineCache(pipelineCache)
+    {}
+
+    PipelineCache& operator=(VkPipelineCache pipelineCache)
+    {
+      m_pipelineCache = pipelineCache;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkPipelineCache() const
+    {
+      return m_pipelineCache;
+    }
+
+    explicit operator bool() const
+    {
+      return m_pipelineCache != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_pipelineCache == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkPipelineCache m_pipelineCache;
+  };
+  static_assert( sizeof( PipelineCache ) == sizeof( VkPipelineCache ), "handle and wrapper have different size!" );
+
+  class DisplayKHR
+  {
+  public:
+    DisplayKHR()
+      : m_displayKHR(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    DisplayKHR(VkDisplayKHR displayKHR)
+       : m_displayKHR(displayKHR)
+    {}
+
+    DisplayKHR& operator=(VkDisplayKHR displayKHR)
+    {
+      m_displayKHR = displayKHR;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkDisplayKHR() const
+    {
+      return m_displayKHR;
+    }
+
+    explicit operator bool() const
+    {
+      return m_displayKHR != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_displayKHR == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkDisplayKHR m_displayKHR;
+  };
+  static_assert( sizeof( DisplayKHR ) == sizeof( VkDisplayKHR ), "handle and wrapper have different size!" );
+
+  class DisplayModeKHR
+  {
+  public:
+    DisplayModeKHR()
+      : m_displayModeKHR(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    DisplayModeKHR(VkDisplayModeKHR displayModeKHR)
+       : m_displayModeKHR(displayModeKHR)
+    {}
+
+    DisplayModeKHR& operator=(VkDisplayModeKHR displayModeKHR)
+    {
+      m_displayModeKHR = displayModeKHR;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkDisplayModeKHR() const
+    {
+      return m_displayModeKHR;
+    }
+
+    explicit operator bool() const
+    {
+      return m_displayModeKHR != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_displayModeKHR == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkDisplayModeKHR m_displayModeKHR;
+  };
+  static_assert( sizeof( DisplayModeKHR ) == sizeof( VkDisplayModeKHR ), "handle and wrapper have different size!" );
+
+  class SurfaceKHR
+  {
+  public:
+    SurfaceKHR()
+      : m_surfaceKHR(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    SurfaceKHR(VkSurfaceKHR surfaceKHR)
+       : m_surfaceKHR(surfaceKHR)
+    {}
+
+    SurfaceKHR& operator=(VkSurfaceKHR surfaceKHR)
+    {
+      m_surfaceKHR = surfaceKHR;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkSurfaceKHR() const
+    {
+      return m_surfaceKHR;
+    }
+
+    explicit operator bool() const
+    {
+      return m_surfaceKHR != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_surfaceKHR == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkSurfaceKHR m_surfaceKHR;
+  };
+  static_assert( sizeof( SurfaceKHR ) == sizeof( VkSurfaceKHR ), "handle and wrapper have different size!" );
+
+  class SwapchainKHR
+  {
+  public:
+    SwapchainKHR()
+      : m_swapchainKHR(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    SwapchainKHR(VkSwapchainKHR swapchainKHR)
+       : m_swapchainKHR(swapchainKHR)
+    {}
+
+    SwapchainKHR& operator=(VkSwapchainKHR swapchainKHR)
+    {
+      m_swapchainKHR = swapchainKHR;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkSwapchainKHR() const
+    {
+      return m_swapchainKHR;
+    }
+
+    explicit operator bool() const
+    {
+      return m_swapchainKHR != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_swapchainKHR == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkSwapchainKHR m_swapchainKHR;
+  };
+  static_assert( sizeof( SwapchainKHR ) == sizeof( VkSwapchainKHR ), "handle and wrapper have different size!" );
+
+  class DebugReportCallbackEXT
+  {
+  public:
+    DebugReportCallbackEXT()
+      : m_debugReportCallbackEXT(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    DebugReportCallbackEXT(VkDebugReportCallbackEXT debugReportCallbackEXT)
+       : m_debugReportCallbackEXT(debugReportCallbackEXT)
+    {}
+
+    DebugReportCallbackEXT& operator=(VkDebugReportCallbackEXT debugReportCallbackEXT)
+    {
+      m_debugReportCallbackEXT = debugReportCallbackEXT;
+      return *this;
+    }
+#endif
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkDebugReportCallbackEXT() const
+    {
+      return m_debugReportCallbackEXT;
+    }
+
+    explicit operator bool() const
+    {
+      return m_debugReportCallbackEXT != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_debugReportCallbackEXT == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkDebugReportCallbackEXT m_debugReportCallbackEXT;
+  };
+  static_assert( sizeof( DebugReportCallbackEXT ) == sizeof( VkDebugReportCallbackEXT ), "handle and wrapper have different size!" );
+
+  struct Offset2D
+  {
+    Offset2D( int32_t x_ = 0, int32_t y_ = 0 )
+      : x( x_ )
+      , y( y_ )
+    {
+    }
+
+    Offset2D( VkOffset2D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Offset2D) );
+    }
+
+    Offset2D& operator=( VkOffset2D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Offset2D) );
+      return *this;
+    }
+
+    Offset2D& setX( int32_t x_ )
+    {
+      x = x_;
+      return *this;
+    }
+
+    Offset2D& setY( int32_t y_ )
+    {
+      y = y_;
+      return *this;
+    }
+
+    operator const VkOffset2D&() const
+    {
+      return *reinterpret_cast<const VkOffset2D*>(this);
+    }
+
+    bool operator==( Offset2D const& rhs ) const
+    {
+      return ( x == rhs.x )
+          && ( y == rhs.y );
+    }
+
+    bool operator!=( Offset2D const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    int32_t x;
+    int32_t y;
+  };
+  static_assert( sizeof( Offset2D ) == sizeof( VkOffset2D ), "struct and wrapper have different size!" );
+
+  struct Offset3D
+  {
+    Offset3D( int32_t x_ = 0, int32_t y_ = 0, int32_t z_ = 0 )
+      : x( x_ )
+      , y( y_ )
+      , z( z_ )
+    {
+    }
+
+    Offset3D( VkOffset3D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Offset3D) );
+    }
+
+    Offset3D& operator=( VkOffset3D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Offset3D) );
+      return *this;
+    }
+
+    Offset3D& setX( int32_t x_ )
+    {
+      x = x_;
+      return *this;
+    }
+
+    Offset3D& setY( int32_t y_ )
+    {
+      y = y_;
+      return *this;
+    }
+
+    Offset3D& setZ( int32_t z_ )
+    {
+      z = z_;
+      return *this;
+    }
+
+    operator const VkOffset3D&() const
+    {
+      return *reinterpret_cast<const VkOffset3D*>(this);
+    }
+
+    bool operator==( Offset3D const& rhs ) const
+    {
+      return ( x == rhs.x )
+          && ( y == rhs.y )
+          && ( z == rhs.z );
+    }
+
+    bool operator!=( Offset3D const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    int32_t x;
+    int32_t y;
+    int32_t z;
+  };
+  static_assert( sizeof( Offset3D ) == sizeof( VkOffset3D ), "struct and wrapper have different size!" );
+
+  struct Extent2D
+  {
+    Extent2D( uint32_t width_ = 0, uint32_t height_ = 0 )
+      : width( width_ )
+      , height( height_ )
+    {
+    }
+
+    Extent2D( VkExtent2D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Extent2D) );
+    }
+
+    Extent2D& operator=( VkExtent2D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Extent2D) );
+      return *this;
+    }
+
+    Extent2D& setWidth( uint32_t width_ )
+    {
+      width = width_;
+      return *this;
+    }
+
+    Extent2D& setHeight( uint32_t height_ )
+    {
+      height = height_;
+      return *this;
+    }
+
+    operator const VkExtent2D&() const
+    {
+      return *reinterpret_cast<const VkExtent2D*>(this);
+    }
+
+    bool operator==( Extent2D const& rhs ) const
+    {
+      return ( width == rhs.width )
+          && ( height == rhs.height );
+    }
+
+    bool operator!=( Extent2D const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t width;
+    uint32_t height;
+  };
+  static_assert( sizeof( Extent2D ) == sizeof( VkExtent2D ), "struct and wrapper have different size!" );
+
+  struct Extent3D
+  {
+    Extent3D( uint32_t width_ = 0, uint32_t height_ = 0, uint32_t depth_ = 0 )
+      : width( width_ )
+      , height( height_ )
+      , depth( depth_ )
+    {
+    }
+
+    Extent3D( VkExtent3D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Extent3D) );
+    }
+
+    Extent3D& operator=( VkExtent3D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Extent3D) );
+      return *this;
+    }
+
+    Extent3D& setWidth( uint32_t width_ )
+    {
+      width = width_;
+      return *this;
+    }
+
+    Extent3D& setHeight( uint32_t height_ )
+    {
+      height = height_;
+      return *this;
+    }
+
+    Extent3D& setDepth( uint32_t depth_ )
+    {
+      depth = depth_;
+      return *this;
+    }
+
+    operator const VkExtent3D&() const
+    {
+      return *reinterpret_cast<const VkExtent3D*>(this);
+    }
+
+    bool operator==( Extent3D const& rhs ) const
+    {
+      return ( width == rhs.width )
+          && ( height == rhs.height )
+          && ( depth == rhs.depth );
+    }
+
+    bool operator!=( Extent3D const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t width;
+    uint32_t height;
+    uint32_t depth;
+  };
+  static_assert( sizeof( Extent3D ) == sizeof( VkExtent3D ), "struct and wrapper have different size!" );
+
+  struct Viewport
+  {
+    Viewport( float x_ = 0, float y_ = 0, float width_ = 0, float height_ = 0, float minDepth_ = 0, float maxDepth_ = 0 )
+      : x( x_ )
+      , y( y_ )
+      , width( width_ )
+      , height( height_ )
+      , minDepth( minDepth_ )
+      , maxDepth( maxDepth_ )
+    {
+    }
+
+    Viewport( VkViewport const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Viewport) );
+    }
+
+    Viewport& operator=( VkViewport const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Viewport) );
+      return *this;
+    }
+
+    Viewport& setX( float x_ )
+    {
+      x = x_;
+      return *this;
+    }
+
+    Viewport& setY( float y_ )
+    {
+      y = y_;
+      return *this;
+    }
+
+    Viewport& setWidth( float width_ )
+    {
+      width = width_;
+      return *this;
+    }
+
+    Viewport& setHeight( float height_ )
+    {
+      height = height_;
+      return *this;
+    }
+
+    Viewport& setMinDepth( float minDepth_ )
+    {
+      minDepth = minDepth_;
+      return *this;
+    }
+
+    Viewport& setMaxDepth( float maxDepth_ )
+    {
+      maxDepth = maxDepth_;
+      return *this;
+    }
+
+    operator const VkViewport&() const
+    {
+      return *reinterpret_cast<const VkViewport*>(this);
+    }
+
+    bool operator==( Viewport const& rhs ) const
+    {
+      return ( x == rhs.x )
+          && ( y == rhs.y )
+          && ( width == rhs.width )
+          && ( height == rhs.height )
+          && ( minDepth == rhs.minDepth )
+          && ( maxDepth == rhs.maxDepth );
+    }
+
+    bool operator!=( Viewport const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    float x;
+    float y;
+    float width;
+    float height;
+    float minDepth;
+    float maxDepth;
+  };
+  static_assert( sizeof( Viewport ) == sizeof( VkViewport ), "struct and wrapper have different size!" );
+
+  struct Rect2D
+  {
+    Rect2D( Offset2D offset_ = Offset2D(), Extent2D extent_ = Extent2D() )
+      : offset( offset_ )
+      , extent( extent_ )
+    {
+    }
+
+    Rect2D( VkRect2D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Rect2D) );
+    }
+
+    Rect2D& operator=( VkRect2D const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Rect2D) );
+      return *this;
+    }
+
+    Rect2D& setOffset( Offset2D offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    Rect2D& setExtent( Extent2D extent_ )
+    {
+      extent = extent_;
+      return *this;
+    }
+
+    operator const VkRect2D&() const
+    {
+      return *reinterpret_cast<const VkRect2D*>(this);
+    }
+
+    bool operator==( Rect2D const& rhs ) const
+    {
+      return ( offset == rhs.offset )
+          && ( extent == rhs.extent );
+    }
+
+    bool operator!=( Rect2D const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Offset2D offset;
+    Extent2D extent;
+  };
+  static_assert( sizeof( Rect2D ) == sizeof( VkRect2D ), "struct and wrapper have different size!" );
+
+  struct ClearRect
+  {
+    ClearRect( Rect2D rect_ = Rect2D(), uint32_t baseArrayLayer_ = 0, uint32_t layerCount_ = 0 )
+      : rect( rect_ )
+      , baseArrayLayer( baseArrayLayer_ )
+      , layerCount( layerCount_ )
+    {
+    }
+
+    ClearRect( VkClearRect const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ClearRect) );
+    }
+
+    ClearRect& operator=( VkClearRect const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ClearRect) );
+      return *this;
+    }
+
+    ClearRect& setRect( Rect2D rect_ )
+    {
+      rect = rect_;
+      return *this;
+    }
+
+    ClearRect& setBaseArrayLayer( uint32_t baseArrayLayer_ )
+    {
+      baseArrayLayer = baseArrayLayer_;
+      return *this;
+    }
+
+    ClearRect& setLayerCount( uint32_t layerCount_ )
+    {
+      layerCount = layerCount_;
+      return *this;
+    }
+
+    operator const VkClearRect&() const
+    {
+      return *reinterpret_cast<const VkClearRect*>(this);
+    }
+
+    bool operator==( ClearRect const& rhs ) const
+    {
+      return ( rect == rhs.rect )
+          && ( baseArrayLayer == rhs.baseArrayLayer )
+          && ( layerCount == rhs.layerCount );
+    }
+
+    bool operator!=( ClearRect const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Rect2D rect;
+    uint32_t baseArrayLayer;
+    uint32_t layerCount;
+  };
+  static_assert( sizeof( ClearRect ) == sizeof( VkClearRect ), "struct and wrapper have different size!" );
+
+  struct ExtensionProperties
+  {
+    operator const VkExtensionProperties&() const
+    {
+      return *reinterpret_cast<const VkExtensionProperties*>(this);
+    }
+
+    bool operator==( ExtensionProperties const& rhs ) const
+    {
+      return ( memcmp( extensionName, rhs.extensionName, VK_MAX_EXTENSION_NAME_SIZE * sizeof( char ) ) == 0 )
+          && ( specVersion == rhs.specVersion );
+    }
+
+    bool operator!=( ExtensionProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    char extensionName[VK_MAX_EXTENSION_NAME_SIZE];
+    uint32_t specVersion;
+  };
+  static_assert( sizeof( ExtensionProperties ) == sizeof( VkExtensionProperties ), "struct and wrapper have different size!" );
+
+  struct LayerProperties
+  {
+    operator const VkLayerProperties&() const
+    {
+      return *reinterpret_cast<const VkLayerProperties*>(this);
+    }
+
+    bool operator==( LayerProperties const& rhs ) const
+    {
+      return ( memcmp( layerName, rhs.layerName, VK_MAX_EXTENSION_NAME_SIZE * sizeof( char ) ) == 0 )
+          && ( specVersion == rhs.specVersion )
+          && ( implementationVersion == rhs.implementationVersion )
+          && ( memcmp( description, rhs.description, VK_MAX_DESCRIPTION_SIZE * sizeof( char ) ) == 0 );
+    }
+
+    bool operator!=( LayerProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    char layerName[VK_MAX_EXTENSION_NAME_SIZE];
+    uint32_t specVersion;
+    uint32_t implementationVersion;
+    char description[VK_MAX_DESCRIPTION_SIZE];
+  };
+  static_assert( sizeof( LayerProperties ) == sizeof( VkLayerProperties ), "struct and wrapper have different size!" );
+
+  struct AllocationCallbacks
+  {
+    AllocationCallbacks( void* pUserData_ = nullptr, PFN_vkAllocationFunction pfnAllocation_ = nullptr, PFN_vkReallocationFunction pfnReallocation_ = nullptr, PFN_vkFreeFunction pfnFree_ = nullptr, PFN_vkInternalAllocationNotification pfnInternalAllocation_ = nullptr, PFN_vkInternalFreeNotification pfnInternalFree_ = nullptr )
+      : pUserData( pUserData_ )
+      , pfnAllocation( pfnAllocation_ )
+      , pfnReallocation( pfnReallocation_ )
+      , pfnFree( pfnFree_ )
+      , pfnInternalAllocation( pfnInternalAllocation_ )
+      , pfnInternalFree( pfnInternalFree_ )
+    {
+    }
+
+    AllocationCallbacks( VkAllocationCallbacks const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(AllocationCallbacks) );
+    }
+
+    AllocationCallbacks& operator=( VkAllocationCallbacks const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(AllocationCallbacks) );
+      return *this;
+    }
+
+    AllocationCallbacks& setPUserData( void* pUserData_ )
+    {
+      pUserData = pUserData_;
+      return *this;
+    }
+
+    AllocationCallbacks& setPfnAllocation( PFN_vkAllocationFunction pfnAllocation_ )
+    {
+      pfnAllocation = pfnAllocation_;
+      return *this;
+    }
+
+    AllocationCallbacks& setPfnReallocation( PFN_vkReallocationFunction pfnReallocation_ )
+    {
+      pfnReallocation = pfnReallocation_;
+      return *this;
+    }
+
+    AllocationCallbacks& setPfnFree( PFN_vkFreeFunction pfnFree_ )
+    {
+      pfnFree = pfnFree_;
+      return *this;
+    }
+
+    AllocationCallbacks& setPfnInternalAllocation( PFN_vkInternalAllocationNotification pfnInternalAllocation_ )
+    {
+      pfnInternalAllocation = pfnInternalAllocation_;
+      return *this;
+    }
+
+    AllocationCallbacks& setPfnInternalFree( PFN_vkInternalFreeNotification pfnInternalFree_ )
+    {
+      pfnInternalFree = pfnInternalFree_;
+      return *this;
+    }
+
+    operator const VkAllocationCallbacks&() const
+    {
+      return *reinterpret_cast<const VkAllocationCallbacks*>(this);
+    }
+
+    bool operator==( AllocationCallbacks const& rhs ) const
+    {
+      return ( pUserData == rhs.pUserData )
+          && ( pfnAllocation == rhs.pfnAllocation )
+          && ( pfnReallocation == rhs.pfnReallocation )
+          && ( pfnFree == rhs.pfnFree )
+          && ( pfnInternalAllocation == rhs.pfnInternalAllocation )
+          && ( pfnInternalFree == rhs.pfnInternalFree );
+    }
+
+    bool operator!=( AllocationCallbacks const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    void* pUserData;
+    PFN_vkAllocationFunction pfnAllocation;
+    PFN_vkReallocationFunction pfnReallocation;
+    PFN_vkFreeFunction pfnFree;
+    PFN_vkInternalAllocationNotification pfnInternalAllocation;
+    PFN_vkInternalFreeNotification pfnInternalFree;
+  };
+  static_assert( sizeof( AllocationCallbacks ) == sizeof( VkAllocationCallbacks ), "struct and wrapper have different size!" );
+
+  struct MemoryRequirements
+  {
+    operator const VkMemoryRequirements&() const
+    {
+      return *reinterpret_cast<const VkMemoryRequirements*>(this);
+    }
+
+    bool operator==( MemoryRequirements const& rhs ) const
+    {
+      return ( size == rhs.size )
+          && ( alignment == rhs.alignment )
+          && ( memoryTypeBits == rhs.memoryTypeBits );
+    }
+
+    bool operator!=( MemoryRequirements const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DeviceSize size;
+    DeviceSize alignment;
+    uint32_t memoryTypeBits;
+  };
+  static_assert( sizeof( MemoryRequirements ) == sizeof( VkMemoryRequirements ), "struct and wrapper have different size!" );
+
+  struct DescriptorBufferInfo
+  {
+    DescriptorBufferInfo( Buffer buffer_ = Buffer(), DeviceSize offset_ = 0, DeviceSize range_ = 0 )
+      : buffer( buffer_ )
+      , offset( offset_ )
+      , range( range_ )
+    {
+    }
+
+    DescriptorBufferInfo( VkDescriptorBufferInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorBufferInfo) );
+    }
+
+    DescriptorBufferInfo& operator=( VkDescriptorBufferInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorBufferInfo) );
+      return *this;
+    }
+
+    DescriptorBufferInfo& setBuffer( Buffer buffer_ )
+    {
+      buffer = buffer_;
+      return *this;
+    }
+
+    DescriptorBufferInfo& setOffset( DeviceSize offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    DescriptorBufferInfo& setRange( DeviceSize range_ )
+    {
+      range = range_;
+      return *this;
+    }
+
+    operator const VkDescriptorBufferInfo&() const
+    {
+      return *reinterpret_cast<const VkDescriptorBufferInfo*>(this);
+    }
+
+    bool operator==( DescriptorBufferInfo const& rhs ) const
+    {
+      return ( buffer == rhs.buffer )
+          && ( offset == rhs.offset )
+          && ( range == rhs.range );
+    }
+
+    bool operator!=( DescriptorBufferInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Buffer buffer;
+    DeviceSize offset;
+    DeviceSize range;
+  };
+  static_assert( sizeof( DescriptorBufferInfo ) == sizeof( VkDescriptorBufferInfo ), "struct and wrapper have different size!" );
+
+  struct SubresourceLayout
+  {
+    operator const VkSubresourceLayout&() const
+    {
+      return *reinterpret_cast<const VkSubresourceLayout*>(this);
+    }
+
+    bool operator==( SubresourceLayout const& rhs ) const
+    {
+      return ( offset == rhs.offset )
+          && ( size == rhs.size )
+          && ( rowPitch == rhs.rowPitch )
+          && ( arrayPitch == rhs.arrayPitch )
+          && ( depthPitch == rhs.depthPitch );
+    }
+
+    bool operator!=( SubresourceLayout const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DeviceSize offset;
+    DeviceSize size;
+    DeviceSize rowPitch;
+    DeviceSize arrayPitch;
+    DeviceSize depthPitch;
+  };
+  static_assert( sizeof( SubresourceLayout ) == sizeof( VkSubresourceLayout ), "struct and wrapper have different size!" );
+
+  struct BufferCopy
+  {
+    BufferCopy( DeviceSize srcOffset_ = 0, DeviceSize dstOffset_ = 0, DeviceSize size_ = 0 )
+      : srcOffset( srcOffset_ )
+      , dstOffset( dstOffset_ )
+      , size( size_ )
+    {
+    }
+
+    BufferCopy( VkBufferCopy const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferCopy) );
+    }
+
+    BufferCopy& operator=( VkBufferCopy const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferCopy) );
+      return *this;
+    }
+
+    BufferCopy& setSrcOffset( DeviceSize srcOffset_ )
+    {
+      srcOffset = srcOffset_;
+      return *this;
+    }
+
+    BufferCopy& setDstOffset( DeviceSize dstOffset_ )
+    {
+      dstOffset = dstOffset_;
+      return *this;
+    }
+
+    BufferCopy& setSize( DeviceSize size_ )
+    {
+      size = size_;
+      return *this;
+    }
+
+    operator const VkBufferCopy&() const
+    {
+      return *reinterpret_cast<const VkBufferCopy*>(this);
+    }
+
+    bool operator==( BufferCopy const& rhs ) const
+    {
+      return ( srcOffset == rhs.srcOffset )
+          && ( dstOffset == rhs.dstOffset )
+          && ( size == rhs.size );
+    }
+
+    bool operator!=( BufferCopy const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DeviceSize srcOffset;
+    DeviceSize dstOffset;
+    DeviceSize size;
+  };
+  static_assert( sizeof( BufferCopy ) == sizeof( VkBufferCopy ), "struct and wrapper have different size!" );
+
+  struct SpecializationMapEntry
+  {
+    SpecializationMapEntry( uint32_t constantID_ = 0, uint32_t offset_ = 0, size_t size_ = 0 )
+      : constantID( constantID_ )
+      , offset( offset_ )
+      , size( size_ )
+    {
+    }
+
+    SpecializationMapEntry( VkSpecializationMapEntry const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SpecializationMapEntry) );
+    }
+
+    SpecializationMapEntry& operator=( VkSpecializationMapEntry const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SpecializationMapEntry) );
+      return *this;
+    }
+
+    SpecializationMapEntry& setConstantID( uint32_t constantID_ )
+    {
+      constantID = constantID_;
+      return *this;
+    }
+
+    SpecializationMapEntry& setOffset( uint32_t offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    SpecializationMapEntry& setSize( size_t size_ )
+    {
+      size = size_;
+      return *this;
+    }
+
+    operator const VkSpecializationMapEntry&() const
+    {
+      return *reinterpret_cast<const VkSpecializationMapEntry*>(this);
+    }
+
+    bool operator==( SpecializationMapEntry const& rhs ) const
+    {
+      return ( constantID == rhs.constantID )
+          && ( offset == rhs.offset )
+          && ( size == rhs.size );
+    }
+
+    bool operator!=( SpecializationMapEntry const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t constantID;
+    uint32_t offset;
+    size_t size;
+  };
+  static_assert( sizeof( SpecializationMapEntry ) == sizeof( VkSpecializationMapEntry ), "struct and wrapper have different size!" );
+
+  struct SpecializationInfo
+  {
+    SpecializationInfo( uint32_t mapEntryCount_ = 0, const SpecializationMapEntry* pMapEntries_ = nullptr, size_t dataSize_ = 0, const void* pData_ = nullptr )
+      : mapEntryCount( mapEntryCount_ )
+      , pMapEntries( pMapEntries_ )
+      , dataSize( dataSize_ )
+      , pData( pData_ )
+    {
+    }
+
+    SpecializationInfo( VkSpecializationInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SpecializationInfo) );
+    }
+
+    SpecializationInfo& operator=( VkSpecializationInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SpecializationInfo) );
+      return *this;
+    }
+
+    SpecializationInfo& setMapEntryCount( uint32_t mapEntryCount_ )
+    {
+      mapEntryCount = mapEntryCount_;
+      return *this;
+    }
+
+    SpecializationInfo& setPMapEntries( const SpecializationMapEntry* pMapEntries_ )
+    {
+      pMapEntries = pMapEntries_;
+      return *this;
+    }
+
+    SpecializationInfo& setDataSize( size_t dataSize_ )
+    {
+      dataSize = dataSize_;
+      return *this;
+    }
+
+    SpecializationInfo& setPData( const void* pData_ )
+    {
+      pData = pData_;
+      return *this;
+    }
+
+    operator const VkSpecializationInfo&() const
+    {
+      return *reinterpret_cast<const VkSpecializationInfo*>(this);
+    }
+
+    bool operator==( SpecializationInfo const& rhs ) const
+    {
+      return ( mapEntryCount == rhs.mapEntryCount )
+          && ( pMapEntries == rhs.pMapEntries )
+          && ( dataSize == rhs.dataSize )
+          && ( pData == rhs.pData );
+    }
+
+    bool operator!=( SpecializationInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t mapEntryCount;
+    const SpecializationMapEntry* pMapEntries;
+    size_t dataSize;
+    const void* pData;
+  };
+  static_assert( sizeof( SpecializationInfo ) == sizeof( VkSpecializationInfo ), "struct and wrapper have different size!" );
+
+  union ClearColorValue
+  {
+    ClearColorValue( const std::array<float,4>& float32_ = { {0} } )
+    {
+      memcpy( &float32, float32_.data(), 4 * sizeof( float ) );
+    }
+
+    ClearColorValue( const std::array<int32_t,4>& int32_ )
+    {
+      memcpy( &int32, int32_.data(), 4 * sizeof( int32_t ) );
+    }
+
+    ClearColorValue( const std::array<uint32_t,4>& uint32_ )
+    {
+      memcpy( &uint32, uint32_.data(), 4 * sizeof( uint32_t ) );
+    }
+
+    ClearColorValue& setFloat32( std::array<float,4> float32_ )
+    {
+      memcpy( &float32, float32_.data(), 4 * sizeof( float ) );
+      return *this;
+    }
+
+    ClearColorValue& setInt32( std::array<int32_t,4> int32_ )
+    {
+      memcpy( &int32, int32_.data(), 4 * sizeof( int32_t ) );
+      return *this;
+    }
+
+    ClearColorValue& setUint32( std::array<uint32_t,4> uint32_ )
+    {
+      memcpy( &uint32, uint32_.data(), 4 * sizeof( uint32_t ) );
+      return *this;
+    }
+
+    operator VkClearColorValue const& () const
+    {
+      return *reinterpret_cast<const VkClearColorValue*>(this);
+    }
+
+    float float32[4];
+    int32_t int32[4];
+    uint32_t uint32[4];
+  };
+
+  struct ClearDepthStencilValue
+  {
+    ClearDepthStencilValue( float depth_ = 0, uint32_t stencil_ = 0 )
+      : depth( depth_ )
+      , stencil( stencil_ )
+    {
+    }
+
+    ClearDepthStencilValue( VkClearDepthStencilValue const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ClearDepthStencilValue) );
+    }
+
+    ClearDepthStencilValue& operator=( VkClearDepthStencilValue const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ClearDepthStencilValue) );
+      return *this;
+    }
+
+    ClearDepthStencilValue& setDepth( float depth_ )
+    {
+      depth = depth_;
+      return *this;
+    }
+
+    ClearDepthStencilValue& setStencil( uint32_t stencil_ )
+    {
+      stencil = stencil_;
+      return *this;
+    }
+
+    operator const VkClearDepthStencilValue&() const
+    {
+      return *reinterpret_cast<const VkClearDepthStencilValue*>(this);
+    }
+
+    bool operator==( ClearDepthStencilValue const& rhs ) const
+    {
+      return ( depth == rhs.depth )
+          && ( stencil == rhs.stencil );
+    }
+
+    bool operator!=( ClearDepthStencilValue const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    float depth;
+    uint32_t stencil;
+  };
+  static_assert( sizeof( ClearDepthStencilValue ) == sizeof( VkClearDepthStencilValue ), "struct and wrapper have different size!" );
+
+  union ClearValue
+  {
+    ClearValue( ClearColorValue color_ = ClearColorValue() )
+    {
+      color = color_;
+    }
+
+    ClearValue( ClearDepthStencilValue depthStencil_ )
+    {
+      depthStencil = depthStencil_;
+    }
+
+    ClearValue& setColor( ClearColorValue color_ )
+    {
+      color = color_;
+      return *this;
+    }
+
+    ClearValue& setDepthStencil( ClearDepthStencilValue depthStencil_ )
+    {
+      depthStencil = depthStencil_;
+      return *this;
+    }
+
+    operator VkClearValue const& () const
+    {
+      return *reinterpret_cast<const VkClearValue*>(this);
+    }
+
+#ifdef VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
+    ClearColorValue color;
+    ClearDepthStencilValue depthStencil;
+#else
+    VkClearColorValue color;
+    VkClearDepthStencilValue depthStencil;
+#endif  // VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
+  };
+
+  struct PhysicalDeviceFeatures
+  {
+    PhysicalDeviceFeatures( Bool32 robustBufferAccess_ = 0, Bool32 fullDrawIndexUint32_ = 0, Bool32 imageCubeArray_ = 0, Bool32 independentBlend_ = 0, Bool32 geometryShader_ = 0, Bool32 tessellationShader_ = 0, Bool32 sampleRateShading_ = 0, Bool32 dualSrcBlend_ = 0, Bool32 logicOp_ = 0, Bool32 multiDrawIndirect_ = 0, Bool32 drawIndirectFirstInstance_ = 0, Bool32 depthClamp_ = 0, Bool32 depthBiasClamp_ = 0, Bool32 fillModeNonSolid_ = 0, Bool32 depthBounds_ = 0, Bool32 wideLines_ = 0, Bool32 largePoints_ = 0, Bool32 alphaToOne_ = 0, Bool32 multiViewport_ = 0, Bool32 samplerAnisotropy_ = 0, Bool32 textureCompressionETC2_ = 0, Bool32 textureCompressionASTC_LDR_ = 0, Bool32 textureCompressionBC_ = 0, Bool32 occlusionQueryPrecise_ = 0, Bool32 pipelineStatisticsQuery_ = 0, Bool32 vertexPipelineStoresAndAtomics_ = 0, Bool32 fragmentStoresAndAtomics_ = 0, Bool32 shaderTessellationAndGeometryPointSize_ = 0, Bool32 shaderImageGatherExtended_ = 0, Bool32 shaderStorageImageExtendedFormats_ = 0, Bool32 shaderStorageImageMultisample_ = 0, Bool32 shaderStorageImageReadWithoutFormat_ = 0, Bool32 shaderStorageImageWriteWithoutFormat_ = 0, Bool32 shaderUniformBufferArrayDynamicIndexing_ = 0, Bool32 shaderSampledImageArrayDynamicIndexing_ = 0, Bool32 shaderStorageBufferArrayDynamicIndexing_ = 0, Bool32 shaderStorageImageArrayDynamicIndexing_ = 0, Bool32 shaderClipDistance_ = 0, Bool32 shaderCullDistance_ = 0, Bool32 shaderFloat64_ = 0, Bool32 shaderInt64_ = 0, Bool32 shaderInt16_ = 0, Bool32 shaderResourceResidency_ = 0, Bool32 shaderResourceMinLod_ = 0, Bool32 sparseBinding_ = 0, Bool32 sparseResidencyBuffer_ = 0, Bool32 sparseResidencyImage2D_ = 0, Bool32 sparseResidencyImage3D_ = 0, Bool32 sparseResidency2Samples_ = 0, Bool32 sparseResidency4Samples_ = 0, Bool32 sparseResidency8Samples_ = 0, Bool32 sparseResidency16Samples_ = 0, Bool32 sparseResidencyAliased_ = 0, Bool32 variableMultisampleRate_ = 0, Bool32 inheritedQueries_ = 0 )
+      : robustBufferAccess( robustBufferAccess_ )
+      , fullDrawIndexUint32( fullDrawIndexUint32_ )
+      , imageCubeArray( imageCubeArray_ )
+      , independentBlend( independentBlend_ )
+      , geometryShader( geometryShader_ )
+      , tessellationShader( tessellationShader_ )
+      , sampleRateShading( sampleRateShading_ )
+      , dualSrcBlend( dualSrcBlend_ )
+      , logicOp( logicOp_ )
+      , multiDrawIndirect( multiDrawIndirect_ )
+      , drawIndirectFirstInstance( drawIndirectFirstInstance_ )
+      , depthClamp( depthClamp_ )
+      , depthBiasClamp( depthBiasClamp_ )
+      , fillModeNonSolid( fillModeNonSolid_ )
+      , depthBounds( depthBounds_ )
+      , wideLines( wideLines_ )
+      , largePoints( largePoints_ )
+      , alphaToOne( alphaToOne_ )
+      , multiViewport( multiViewport_ )
+      , samplerAnisotropy( samplerAnisotropy_ )
+      , textureCompressionETC2( textureCompressionETC2_ )
+      , textureCompressionASTC_LDR( textureCompressionASTC_LDR_ )
+      , textureCompressionBC( textureCompressionBC_ )
+      , occlusionQueryPrecise( occlusionQueryPrecise_ )
+      , pipelineStatisticsQuery( pipelineStatisticsQuery_ )
+      , vertexPipelineStoresAndAtomics( vertexPipelineStoresAndAtomics_ )
+      , fragmentStoresAndAtomics( fragmentStoresAndAtomics_ )
+      , shaderTessellationAndGeometryPointSize( shaderTessellationAndGeometryPointSize_ )
+      , shaderImageGatherExtended( shaderImageGatherExtended_ )
+      , shaderStorageImageExtendedFormats( shaderStorageImageExtendedFormats_ )
+      , shaderStorageImageMultisample( shaderStorageImageMultisample_ )
+      , shaderStorageImageReadWithoutFormat( shaderStorageImageReadWithoutFormat_ )
+      , shaderStorageImageWriteWithoutFormat( shaderStorageImageWriteWithoutFormat_ )
+      , shaderUniformBufferArrayDynamicIndexing( shaderUniformBufferArrayDynamicIndexing_ )
+      , shaderSampledImageArrayDynamicIndexing( shaderSampledImageArrayDynamicIndexing_ )
+      , shaderStorageBufferArrayDynamicIndexing( shaderStorageBufferArrayDynamicIndexing_ )
+      , shaderStorageImageArrayDynamicIndexing( shaderStorageImageArrayDynamicIndexing_ )
+      , shaderClipDistance( shaderClipDistance_ )
+      , shaderCullDistance( shaderCullDistance_ )
+      , shaderFloat64( shaderFloat64_ )
+      , shaderInt64( shaderInt64_ )
+      , shaderInt16( shaderInt16_ )
+      , shaderResourceResidency( shaderResourceResidency_ )
+      , shaderResourceMinLod( shaderResourceMinLod_ )
+      , sparseBinding( sparseBinding_ )
+      , sparseResidencyBuffer( sparseResidencyBuffer_ )
+      , sparseResidencyImage2D( sparseResidencyImage2D_ )
+      , sparseResidencyImage3D( sparseResidencyImage3D_ )
+      , sparseResidency2Samples( sparseResidency2Samples_ )
+      , sparseResidency4Samples( sparseResidency4Samples_ )
+      , sparseResidency8Samples( sparseResidency8Samples_ )
+      , sparseResidency16Samples( sparseResidency16Samples_ )
+      , sparseResidencyAliased( sparseResidencyAliased_ )
+      , variableMultisampleRate( variableMultisampleRate_ )
+      , inheritedQueries( inheritedQueries_ )
+    {
+    }
+
+    PhysicalDeviceFeatures( VkPhysicalDeviceFeatures const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PhysicalDeviceFeatures) );
+    }
+
+    PhysicalDeviceFeatures& operator=( VkPhysicalDeviceFeatures const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PhysicalDeviceFeatures) );
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setRobustBufferAccess( Bool32 robustBufferAccess_ )
+    {
+      robustBufferAccess = robustBufferAccess_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setFullDrawIndexUint32( Bool32 fullDrawIndexUint32_ )
+    {
+      fullDrawIndexUint32 = fullDrawIndexUint32_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setImageCubeArray( Bool32 imageCubeArray_ )
+    {
+      imageCubeArray = imageCubeArray_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setIndependentBlend( Bool32 independentBlend_ )
+    {
+      independentBlend = independentBlend_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setGeometryShader( Bool32 geometryShader_ )
+    {
+      geometryShader = geometryShader_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setTessellationShader( Bool32 tessellationShader_ )
+    {
+      tessellationShader = tessellationShader_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSampleRateShading( Bool32 sampleRateShading_ )
+    {
+      sampleRateShading = sampleRateShading_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setDualSrcBlend( Bool32 dualSrcBlend_ )
+    {
+      dualSrcBlend = dualSrcBlend_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setLogicOp( Bool32 logicOp_ )
+    {
+      logicOp = logicOp_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setMultiDrawIndirect( Bool32 multiDrawIndirect_ )
+    {
+      multiDrawIndirect = multiDrawIndirect_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setDrawIndirectFirstInstance( Bool32 drawIndirectFirstInstance_ )
+    {
+      drawIndirectFirstInstance = drawIndirectFirstInstance_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setDepthClamp( Bool32 depthClamp_ )
+    {
+      depthClamp = depthClamp_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setDepthBiasClamp( Bool32 depthBiasClamp_ )
+    {
+      depthBiasClamp = depthBiasClamp_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setFillModeNonSolid( Bool32 fillModeNonSolid_ )
+    {
+      fillModeNonSolid = fillModeNonSolid_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setDepthBounds( Bool32 depthBounds_ )
+    {
+      depthBounds = depthBounds_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setWideLines( Bool32 wideLines_ )
+    {
+      wideLines = wideLines_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setLargePoints( Bool32 largePoints_ )
+    {
+      largePoints = largePoints_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setAlphaToOne( Bool32 alphaToOne_ )
+    {
+      alphaToOne = alphaToOne_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setMultiViewport( Bool32 multiViewport_ )
+    {
+      multiViewport = multiViewport_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSamplerAnisotropy( Bool32 samplerAnisotropy_ )
+    {
+      samplerAnisotropy = samplerAnisotropy_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setTextureCompressionETC2( Bool32 textureCompressionETC2_ )
+    {
+      textureCompressionETC2 = textureCompressionETC2_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setTextureCompressionASTC_LDR( Bool32 textureCompressionASTC_LDR_ )
+    {
+      textureCompressionASTC_LDR = textureCompressionASTC_LDR_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setTextureCompressionBC( Bool32 textureCompressionBC_ )
+    {
+      textureCompressionBC = textureCompressionBC_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setOcclusionQueryPrecise( Bool32 occlusionQueryPrecise_ )
+    {
+      occlusionQueryPrecise = occlusionQueryPrecise_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setPipelineStatisticsQuery( Bool32 pipelineStatisticsQuery_ )
+    {
+      pipelineStatisticsQuery = pipelineStatisticsQuery_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setVertexPipelineStoresAndAtomics( Bool32 vertexPipelineStoresAndAtomics_ )
+    {
+      vertexPipelineStoresAndAtomics = vertexPipelineStoresAndAtomics_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setFragmentStoresAndAtomics( Bool32 fragmentStoresAndAtomics_ )
+    {
+      fragmentStoresAndAtomics = fragmentStoresAndAtomics_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderTessellationAndGeometryPointSize( Bool32 shaderTessellationAndGeometryPointSize_ )
+    {
+      shaderTessellationAndGeometryPointSize = shaderTessellationAndGeometryPointSize_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderImageGatherExtended( Bool32 shaderImageGatherExtended_ )
+    {
+      shaderImageGatherExtended = shaderImageGatherExtended_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderStorageImageExtendedFormats( Bool32 shaderStorageImageExtendedFormats_ )
+    {
+      shaderStorageImageExtendedFormats = shaderStorageImageExtendedFormats_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderStorageImageMultisample( Bool32 shaderStorageImageMultisample_ )
+    {
+      shaderStorageImageMultisample = shaderStorageImageMultisample_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderStorageImageReadWithoutFormat( Bool32 shaderStorageImageReadWithoutFormat_ )
+    {
+      shaderStorageImageReadWithoutFormat = shaderStorageImageReadWithoutFormat_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderStorageImageWriteWithoutFormat( Bool32 shaderStorageImageWriteWithoutFormat_ )
+    {
+      shaderStorageImageWriteWithoutFormat = shaderStorageImageWriteWithoutFormat_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderUniformBufferArrayDynamicIndexing( Bool32 shaderUniformBufferArrayDynamicIndexing_ )
+    {
+      shaderUniformBufferArrayDynamicIndexing = shaderUniformBufferArrayDynamicIndexing_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderSampledImageArrayDynamicIndexing( Bool32 shaderSampledImageArrayDynamicIndexing_ )
+    {
+      shaderSampledImageArrayDynamicIndexing = shaderSampledImageArrayDynamicIndexing_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderStorageBufferArrayDynamicIndexing( Bool32 shaderStorageBufferArrayDynamicIndexing_ )
+    {
+      shaderStorageBufferArrayDynamicIndexing = shaderStorageBufferArrayDynamicIndexing_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderStorageImageArrayDynamicIndexing( Bool32 shaderStorageImageArrayDynamicIndexing_ )
+    {
+      shaderStorageImageArrayDynamicIndexing = shaderStorageImageArrayDynamicIndexing_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderClipDistance( Bool32 shaderClipDistance_ )
+    {
+      shaderClipDistance = shaderClipDistance_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderCullDistance( Bool32 shaderCullDistance_ )
+    {
+      shaderCullDistance = shaderCullDistance_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderFloat64( Bool32 shaderFloat64_ )
+    {
+      shaderFloat64 = shaderFloat64_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderInt64( Bool32 shaderInt64_ )
+    {
+      shaderInt64 = shaderInt64_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderInt16( Bool32 shaderInt16_ )
+    {
+      shaderInt16 = shaderInt16_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderResourceResidency( Bool32 shaderResourceResidency_ )
+    {
+      shaderResourceResidency = shaderResourceResidency_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setShaderResourceMinLod( Bool32 shaderResourceMinLod_ )
+    {
+      shaderResourceMinLod = shaderResourceMinLod_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseBinding( Bool32 sparseBinding_ )
+    {
+      sparseBinding = sparseBinding_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseResidencyBuffer( Bool32 sparseResidencyBuffer_ )
+    {
+      sparseResidencyBuffer = sparseResidencyBuffer_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseResidencyImage2D( Bool32 sparseResidencyImage2D_ )
+    {
+      sparseResidencyImage2D = sparseResidencyImage2D_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseResidencyImage3D( Bool32 sparseResidencyImage3D_ )
+    {
+      sparseResidencyImage3D = sparseResidencyImage3D_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseResidency2Samples( Bool32 sparseResidency2Samples_ )
+    {
+      sparseResidency2Samples = sparseResidency2Samples_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseResidency4Samples( Bool32 sparseResidency4Samples_ )
+    {
+      sparseResidency4Samples = sparseResidency4Samples_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseResidency8Samples( Bool32 sparseResidency8Samples_ )
+    {
+      sparseResidency8Samples = sparseResidency8Samples_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseResidency16Samples( Bool32 sparseResidency16Samples_ )
+    {
+      sparseResidency16Samples = sparseResidency16Samples_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setSparseResidencyAliased( Bool32 sparseResidencyAliased_ )
+    {
+      sparseResidencyAliased = sparseResidencyAliased_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setVariableMultisampleRate( Bool32 variableMultisampleRate_ )
+    {
+      variableMultisampleRate = variableMultisampleRate_;
+      return *this;
+    }
+
+    PhysicalDeviceFeatures& setInheritedQueries( Bool32 inheritedQueries_ )
+    {
+      inheritedQueries = inheritedQueries_;
+      return *this;
+    }
+
+    operator const VkPhysicalDeviceFeatures&() const
+    {
+      return *reinterpret_cast<const VkPhysicalDeviceFeatures*>(this);
+    }
+
+    bool operator==( PhysicalDeviceFeatures const& rhs ) const
+    {
+      return ( robustBufferAccess == rhs.robustBufferAccess )
+          && ( fullDrawIndexUint32 == rhs.fullDrawIndexUint32 )
+          && ( imageCubeArray == rhs.imageCubeArray )
+          && ( independentBlend == rhs.independentBlend )
+          && ( geometryShader == rhs.geometryShader )
+          && ( tessellationShader == rhs.tessellationShader )
+          && ( sampleRateShading == rhs.sampleRateShading )
+          && ( dualSrcBlend == rhs.dualSrcBlend )
+          && ( logicOp == rhs.logicOp )
+          && ( multiDrawIndirect == rhs.multiDrawIndirect )
+          && ( drawIndirectFirstInstance == rhs.drawIndirectFirstInstance )
+          && ( depthClamp == rhs.depthClamp )
+          && ( depthBiasClamp == rhs.depthBiasClamp )
+          && ( fillModeNonSolid == rhs.fillModeNonSolid )
+          && ( depthBounds == rhs.depthBounds )
+          && ( wideLines == rhs.wideLines )
+          && ( largePoints == rhs.largePoints )
+          && ( alphaToOne == rhs.alphaToOne )
+          && ( multiViewport == rhs.multiViewport )
+          && ( samplerAnisotropy == rhs.samplerAnisotropy )
+          && ( textureCompressionETC2 == rhs.textureCompressionETC2 )
+          && ( textureCompressionASTC_LDR == rhs.textureCompressionASTC_LDR )
+          && ( textureCompressionBC == rhs.textureCompressionBC )
+          && ( occlusionQueryPrecise == rhs.occlusionQueryPrecise )
+          && ( pipelineStatisticsQuery == rhs.pipelineStatisticsQuery )
+          && ( vertexPipelineStoresAndAtomics == rhs.vertexPipelineStoresAndAtomics )
+          && ( fragmentStoresAndAtomics == rhs.fragmentStoresAndAtomics )
+          && ( shaderTessellationAndGeometryPointSize == rhs.shaderTessellationAndGeometryPointSize )
+          && ( shaderImageGatherExtended == rhs.shaderImageGatherExtended )
+          && ( shaderStorageImageExtendedFormats == rhs.shaderStorageImageExtendedFormats )
+          && ( shaderStorageImageMultisample == rhs.shaderStorageImageMultisample )
+          && ( shaderStorageImageReadWithoutFormat == rhs.shaderStorageImageReadWithoutFormat )
+          && ( shaderStorageImageWriteWithoutFormat == rhs.shaderStorageImageWriteWithoutFormat )
+          && ( shaderUniformBufferArrayDynamicIndexing == rhs.shaderUniformBufferArrayDynamicIndexing )
+          && ( shaderSampledImageArrayDynamicIndexing == rhs.shaderSampledImageArrayDynamicIndexing )
+          && ( shaderStorageBufferArrayDynamicIndexing == rhs.shaderStorageBufferArrayDynamicIndexing )
+          && ( shaderStorageImageArrayDynamicIndexing == rhs.shaderStorageImageArrayDynamicIndexing )
+          && ( shaderClipDistance == rhs.shaderClipDistance )
+          && ( shaderCullDistance == rhs.shaderCullDistance )
+          && ( shaderFloat64 == rhs.shaderFloat64 )
+          && ( shaderInt64 == rhs.shaderInt64 )
+          && ( shaderInt16 == rhs.shaderInt16 )
+          && ( shaderResourceResidency == rhs.shaderResourceResidency )
+          && ( shaderResourceMinLod == rhs.shaderResourceMinLod )
+          && ( sparseBinding == rhs.sparseBinding )
+          && ( sparseResidencyBuffer == rhs.sparseResidencyBuffer )
+          && ( sparseResidencyImage2D == rhs.sparseResidencyImage2D )
+          && ( sparseResidencyImage3D == rhs.sparseResidencyImage3D )
+          && ( sparseResidency2Samples == rhs.sparseResidency2Samples )
+          && ( sparseResidency4Samples == rhs.sparseResidency4Samples )
+          && ( sparseResidency8Samples == rhs.sparseResidency8Samples )
+          && ( sparseResidency16Samples == rhs.sparseResidency16Samples )
+          && ( sparseResidencyAliased == rhs.sparseResidencyAliased )
+          && ( variableMultisampleRate == rhs.variableMultisampleRate )
+          && ( inheritedQueries == rhs.inheritedQueries );
+    }
+
+    bool operator!=( PhysicalDeviceFeatures const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Bool32 robustBufferAccess;
+    Bool32 fullDrawIndexUint32;
+    Bool32 imageCubeArray;
+    Bool32 independentBlend;
+    Bool32 geometryShader;
+    Bool32 tessellationShader;
+    Bool32 sampleRateShading;
+    Bool32 dualSrcBlend;
+    Bool32 logicOp;
+    Bool32 multiDrawIndirect;
+    Bool32 drawIndirectFirstInstance;
+    Bool32 depthClamp;
+    Bool32 depthBiasClamp;
+    Bool32 fillModeNonSolid;
+    Bool32 depthBounds;
+    Bool32 wideLines;
+    Bool32 largePoints;
+    Bool32 alphaToOne;
+    Bool32 multiViewport;
+    Bool32 samplerAnisotropy;
+    Bool32 textureCompressionETC2;
+    Bool32 textureCompressionASTC_LDR;
+    Bool32 textureCompressionBC;
+    Bool32 occlusionQueryPrecise;
+    Bool32 pipelineStatisticsQuery;
+    Bool32 vertexPipelineStoresAndAtomics;
+    Bool32 fragmentStoresAndAtomics;
+    Bool32 shaderTessellationAndGeometryPointSize;
+    Bool32 shaderImageGatherExtended;
+    Bool32 shaderStorageImageExtendedFormats;
+    Bool32 shaderStorageImageMultisample;
+    Bool32 shaderStorageImageReadWithoutFormat;
+    Bool32 shaderStorageImageWriteWithoutFormat;
+    Bool32 shaderUniformBufferArrayDynamicIndexing;
+    Bool32 shaderSampledImageArrayDynamicIndexing;
+    Bool32 shaderStorageBufferArrayDynamicIndexing;
+    Bool32 shaderStorageImageArrayDynamicIndexing;
+    Bool32 shaderClipDistance;
+    Bool32 shaderCullDistance;
+    Bool32 shaderFloat64;
+    Bool32 shaderInt64;
+    Bool32 shaderInt16;
+    Bool32 shaderResourceResidency;
+    Bool32 shaderResourceMinLod;
+    Bool32 sparseBinding;
+    Bool32 sparseResidencyBuffer;
+    Bool32 sparseResidencyImage2D;
+    Bool32 sparseResidencyImage3D;
+    Bool32 sparseResidency2Samples;
+    Bool32 sparseResidency4Samples;
+    Bool32 sparseResidency8Samples;
+    Bool32 sparseResidency16Samples;
+    Bool32 sparseResidencyAliased;
+    Bool32 variableMultisampleRate;
+    Bool32 inheritedQueries;
+  };
+  static_assert( sizeof( PhysicalDeviceFeatures ) == sizeof( VkPhysicalDeviceFeatures ), "struct and wrapper have different size!" );
+
+  struct PhysicalDeviceSparseProperties
+  {
+    operator const VkPhysicalDeviceSparseProperties&() const
+    {
+      return *reinterpret_cast<const VkPhysicalDeviceSparseProperties*>(this);
+    }
+
+    bool operator==( PhysicalDeviceSparseProperties const& rhs ) const
+    {
+      return ( residencyStandard2DBlockShape == rhs.residencyStandard2DBlockShape )
+          && ( residencyStandard2DMultisampleBlockShape == rhs.residencyStandard2DMultisampleBlockShape )
+          && ( residencyStandard3DBlockShape == rhs.residencyStandard3DBlockShape )
+          && ( residencyAlignedMipSize == rhs.residencyAlignedMipSize )
+          && ( residencyNonResidentStrict == rhs.residencyNonResidentStrict );
+    }
+
+    bool operator!=( PhysicalDeviceSparseProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Bool32 residencyStandard2DBlockShape;
+    Bool32 residencyStandard2DMultisampleBlockShape;
+    Bool32 residencyStandard3DBlockShape;
+    Bool32 residencyAlignedMipSize;
+    Bool32 residencyNonResidentStrict;
+  };
+  static_assert( sizeof( PhysicalDeviceSparseProperties ) == sizeof( VkPhysicalDeviceSparseProperties ), "struct and wrapper have different size!" );
+
+  struct DrawIndirectCommand
+  {
+    DrawIndirectCommand( uint32_t vertexCount_ = 0, uint32_t instanceCount_ = 0, uint32_t firstVertex_ = 0, uint32_t firstInstance_ = 0 )
+      : vertexCount( vertexCount_ )
+      , instanceCount( instanceCount_ )
+      , firstVertex( firstVertex_ )
+      , firstInstance( firstInstance_ )
+    {
+    }
+
+    DrawIndirectCommand( VkDrawIndirectCommand const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DrawIndirectCommand) );
+    }
+
+    DrawIndirectCommand& operator=( VkDrawIndirectCommand const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DrawIndirectCommand) );
+      return *this;
+    }
+
+    DrawIndirectCommand& setVertexCount( uint32_t vertexCount_ )
+    {
+      vertexCount = vertexCount_;
+      return *this;
+    }
+
+    DrawIndirectCommand& setInstanceCount( uint32_t instanceCount_ )
+    {
+      instanceCount = instanceCount_;
+      return *this;
+    }
+
+    DrawIndirectCommand& setFirstVertex( uint32_t firstVertex_ )
+    {
+      firstVertex = firstVertex_;
+      return *this;
+    }
+
+    DrawIndirectCommand& setFirstInstance( uint32_t firstInstance_ )
+    {
+      firstInstance = firstInstance_;
+      return *this;
+    }
+
+    operator const VkDrawIndirectCommand&() const
+    {
+      return *reinterpret_cast<const VkDrawIndirectCommand*>(this);
+    }
+
+    bool operator==( DrawIndirectCommand const& rhs ) const
+    {
+      return ( vertexCount == rhs.vertexCount )
+          && ( instanceCount == rhs.instanceCount )
+          && ( firstVertex == rhs.firstVertex )
+          && ( firstInstance == rhs.firstInstance );
+    }
+
+    bool operator!=( DrawIndirectCommand const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t vertexCount;
+    uint32_t instanceCount;
+    uint32_t firstVertex;
+    uint32_t firstInstance;
+  };
+  static_assert( sizeof( DrawIndirectCommand ) == sizeof( VkDrawIndirectCommand ), "struct and wrapper have different size!" );
+
+  struct DrawIndexedIndirectCommand
+  {
+    DrawIndexedIndirectCommand( uint32_t indexCount_ = 0, uint32_t instanceCount_ = 0, uint32_t firstIndex_ = 0, int32_t vertexOffset_ = 0, uint32_t firstInstance_ = 0 )
+      : indexCount( indexCount_ )
+      , instanceCount( instanceCount_ )
+      , firstIndex( firstIndex_ )
+      , vertexOffset( vertexOffset_ )
+      , firstInstance( firstInstance_ )
+    {
+    }
+
+    DrawIndexedIndirectCommand( VkDrawIndexedIndirectCommand const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DrawIndexedIndirectCommand) );
+    }
+
+    DrawIndexedIndirectCommand& operator=( VkDrawIndexedIndirectCommand const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DrawIndexedIndirectCommand) );
+      return *this;
+    }
+
+    DrawIndexedIndirectCommand& setIndexCount( uint32_t indexCount_ )
+    {
+      indexCount = indexCount_;
+      return *this;
+    }
+
+    DrawIndexedIndirectCommand& setInstanceCount( uint32_t instanceCount_ )
+    {
+      instanceCount = instanceCount_;
+      return *this;
+    }
+
+    DrawIndexedIndirectCommand& setFirstIndex( uint32_t firstIndex_ )
+    {
+      firstIndex = firstIndex_;
+      return *this;
+    }
+
+    DrawIndexedIndirectCommand& setVertexOffset( int32_t vertexOffset_ )
+    {
+      vertexOffset = vertexOffset_;
+      return *this;
+    }
+
+    DrawIndexedIndirectCommand& setFirstInstance( uint32_t firstInstance_ )
+    {
+      firstInstance = firstInstance_;
+      return *this;
+    }
+
+    operator const VkDrawIndexedIndirectCommand&() const
+    {
+      return *reinterpret_cast<const VkDrawIndexedIndirectCommand*>(this);
+    }
+
+    bool operator==( DrawIndexedIndirectCommand const& rhs ) const
+    {
+      return ( indexCount == rhs.indexCount )
+          && ( instanceCount == rhs.instanceCount )
+          && ( firstIndex == rhs.firstIndex )
+          && ( vertexOffset == rhs.vertexOffset )
+          && ( firstInstance == rhs.firstInstance );
+    }
+
+    bool operator!=( DrawIndexedIndirectCommand const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t indexCount;
+    uint32_t instanceCount;
+    uint32_t firstIndex;
+    int32_t vertexOffset;
+    uint32_t firstInstance;
+  };
+  static_assert( sizeof( DrawIndexedIndirectCommand ) == sizeof( VkDrawIndexedIndirectCommand ), "struct and wrapper have different size!" );
+
+  struct DispatchIndirectCommand
+  {
+    DispatchIndirectCommand( uint32_t x_ = 0, uint32_t y_ = 0, uint32_t z_ = 0 )
+      : x( x_ )
+      , y( y_ )
+      , z( z_ )
+    {
+    }
+
+    DispatchIndirectCommand( VkDispatchIndirectCommand const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DispatchIndirectCommand) );
+    }
+
+    DispatchIndirectCommand& operator=( VkDispatchIndirectCommand const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DispatchIndirectCommand) );
+      return *this;
+    }
+
+    DispatchIndirectCommand& setX( uint32_t x_ )
+    {
+      x = x_;
+      return *this;
+    }
+
+    DispatchIndirectCommand& setY( uint32_t y_ )
+    {
+      y = y_;
+      return *this;
+    }
+
+    DispatchIndirectCommand& setZ( uint32_t z_ )
+    {
+      z = z_;
+      return *this;
+    }
+
+    operator const VkDispatchIndirectCommand&() const
+    {
+      return *reinterpret_cast<const VkDispatchIndirectCommand*>(this);
+    }
+
+    bool operator==( DispatchIndirectCommand const& rhs ) const
+    {
+      return ( x == rhs.x )
+          && ( y == rhs.y )
+          && ( z == rhs.z );
+    }
+
+    bool operator!=( DispatchIndirectCommand const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t x;
+    uint32_t y;
+    uint32_t z;
+  };
+  static_assert( sizeof( DispatchIndirectCommand ) == sizeof( VkDispatchIndirectCommand ), "struct and wrapper have different size!" );
+
+  struct DisplayPlanePropertiesKHR
+  {
+    DisplayPlanePropertiesKHR( DisplayKHR currentDisplay_ = DisplayKHR(), uint32_t currentStackIndex_ = 0 )
+      : currentDisplay( currentDisplay_ )
+      , currentStackIndex( currentStackIndex_ )
+    {
+    }
+
+    DisplayPlanePropertiesKHR( VkDisplayPlanePropertiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayPlanePropertiesKHR) );
+    }
+
+    DisplayPlanePropertiesKHR& operator=( VkDisplayPlanePropertiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayPlanePropertiesKHR) );
+      return *this;
+    }
+
+    DisplayPlanePropertiesKHR& setCurrentDisplay( DisplayKHR currentDisplay_ )
+    {
+      currentDisplay = currentDisplay_;
+      return *this;
+    }
+
+    DisplayPlanePropertiesKHR& setCurrentStackIndex( uint32_t currentStackIndex_ )
+    {
+      currentStackIndex = currentStackIndex_;
+      return *this;
+    }
+
+    operator const VkDisplayPlanePropertiesKHR&() const
+    {
+      return *reinterpret_cast<const VkDisplayPlanePropertiesKHR*>(this);
+    }
+
+    bool operator==( DisplayPlanePropertiesKHR const& rhs ) const
+    {
+      return ( currentDisplay == rhs.currentDisplay )
+          && ( currentStackIndex == rhs.currentStackIndex );
+    }
+
+    bool operator!=( DisplayPlanePropertiesKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DisplayKHR currentDisplay;
+    uint32_t currentStackIndex;
+  };
+  static_assert( sizeof( DisplayPlanePropertiesKHR ) == sizeof( VkDisplayPlanePropertiesKHR ), "struct and wrapper have different size!" );
+
+  struct DisplayModeParametersKHR
+  {
+    DisplayModeParametersKHR( Extent2D visibleRegion_ = Extent2D(), uint32_t refreshRate_ = 0 )
+      : visibleRegion( visibleRegion_ )
+      , refreshRate( refreshRate_ )
+    {
+    }
+
+    DisplayModeParametersKHR( VkDisplayModeParametersKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayModeParametersKHR) );
+    }
+
+    DisplayModeParametersKHR& operator=( VkDisplayModeParametersKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayModeParametersKHR) );
+      return *this;
+    }
+
+    DisplayModeParametersKHR& setVisibleRegion( Extent2D visibleRegion_ )
+    {
+      visibleRegion = visibleRegion_;
+      return *this;
+    }
+
+    DisplayModeParametersKHR& setRefreshRate( uint32_t refreshRate_ )
+    {
+      refreshRate = refreshRate_;
+      return *this;
+    }
+
+    operator const VkDisplayModeParametersKHR&() const
+    {
+      return *reinterpret_cast<const VkDisplayModeParametersKHR*>(this);
+    }
+
+    bool operator==( DisplayModeParametersKHR const& rhs ) const
+    {
+      return ( visibleRegion == rhs.visibleRegion )
+          && ( refreshRate == rhs.refreshRate );
+    }
+
+    bool operator!=( DisplayModeParametersKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Extent2D visibleRegion;
+    uint32_t refreshRate;
+  };
+  static_assert( sizeof( DisplayModeParametersKHR ) == sizeof( VkDisplayModeParametersKHR ), "struct and wrapper have different size!" );
+
+  struct DisplayModePropertiesKHR
+  {
+    DisplayModePropertiesKHR( DisplayModeKHR displayMode_ = DisplayModeKHR(), DisplayModeParametersKHR parameters_ = DisplayModeParametersKHR() )
+      : displayMode( displayMode_ )
+      , parameters( parameters_ )
+    {
+    }
+
+    DisplayModePropertiesKHR( VkDisplayModePropertiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayModePropertiesKHR) );
+    }
+
+    DisplayModePropertiesKHR& operator=( VkDisplayModePropertiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayModePropertiesKHR) );
+      return *this;
+    }
+
+    DisplayModePropertiesKHR& setDisplayMode( DisplayModeKHR displayMode_ )
+    {
+      displayMode = displayMode_;
+      return *this;
+    }
+
+    DisplayModePropertiesKHR& setParameters( DisplayModeParametersKHR parameters_ )
+    {
+      parameters = parameters_;
+      return *this;
+    }
+
+    operator const VkDisplayModePropertiesKHR&() const
+    {
+      return *reinterpret_cast<const VkDisplayModePropertiesKHR*>(this);
+    }
+
+    bool operator==( DisplayModePropertiesKHR const& rhs ) const
+    {
+      return ( displayMode == rhs.displayMode )
+          && ( parameters == rhs.parameters );
+    }
+
+    bool operator!=( DisplayModePropertiesKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DisplayModeKHR displayMode;
+    DisplayModeParametersKHR parameters;
+  };
+  static_assert( sizeof( DisplayModePropertiesKHR ) == sizeof( VkDisplayModePropertiesKHR ), "struct and wrapper have different size!" );
+
+  enum class ImageLayout
+  {
+    eUndefined = VK_IMAGE_LAYOUT_UNDEFINED,
+    eGeneral = VK_IMAGE_LAYOUT_GENERAL,
+    eColorAttachmentOptimal = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+    eDepthStencilAttachmentOptimal = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+    eDepthStencilReadOnlyOptimal = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
+    eShaderReadOnlyOptimal = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+    eTransferSrcOptimal = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+    eTransferDstOptimal = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+    ePreinitialized = VK_IMAGE_LAYOUT_PREINITIALIZED,
+    ePresentSrcKHR = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
+  };
+
+  struct DescriptorImageInfo
+  {
+    DescriptorImageInfo( Sampler sampler_ = Sampler(), ImageView imageView_ = ImageView(), ImageLayout imageLayout_ = ImageLayout::eUndefined )
+      : sampler( sampler_ )
+      , imageView( imageView_ )
+      , imageLayout( imageLayout_ )
+    {
+    }
+
+    DescriptorImageInfo( VkDescriptorImageInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorImageInfo) );
+    }
+
+    DescriptorImageInfo& operator=( VkDescriptorImageInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorImageInfo) );
+      return *this;
+    }
+
+    DescriptorImageInfo& setSampler( Sampler sampler_ )
+    {
+      sampler = sampler_;
+      return *this;
+    }
+
+    DescriptorImageInfo& setImageView( ImageView imageView_ )
+    {
+      imageView = imageView_;
+      return *this;
+    }
+
+    DescriptorImageInfo& setImageLayout( ImageLayout imageLayout_ )
+    {
+      imageLayout = imageLayout_;
+      return *this;
+    }
+
+    operator const VkDescriptorImageInfo&() const
+    {
+      return *reinterpret_cast<const VkDescriptorImageInfo*>(this);
+    }
+
+    bool operator==( DescriptorImageInfo const& rhs ) const
+    {
+      return ( sampler == rhs.sampler )
+          && ( imageView == rhs.imageView )
+          && ( imageLayout == rhs.imageLayout );
+    }
+
+    bool operator!=( DescriptorImageInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Sampler sampler;
+    ImageView imageView;
+    ImageLayout imageLayout;
+  };
+  static_assert( sizeof( DescriptorImageInfo ) == sizeof( VkDescriptorImageInfo ), "struct and wrapper have different size!" );
+
+  struct AttachmentReference
+  {
+    AttachmentReference( uint32_t attachment_ = 0, ImageLayout layout_ = ImageLayout::eUndefined )
+      : attachment( attachment_ )
+      , layout( layout_ )
+    {
+    }
+
+    AttachmentReference( VkAttachmentReference const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(AttachmentReference) );
+    }
+
+    AttachmentReference& operator=( VkAttachmentReference const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(AttachmentReference) );
+      return *this;
+    }
+
+    AttachmentReference& setAttachment( uint32_t attachment_ )
+    {
+      attachment = attachment_;
+      return *this;
+    }
+
+    AttachmentReference& setLayout( ImageLayout layout_ )
+    {
+      layout = layout_;
+      return *this;
+    }
+
+    operator const VkAttachmentReference&() const
+    {
+      return *reinterpret_cast<const VkAttachmentReference*>(this);
+    }
+
+    bool operator==( AttachmentReference const& rhs ) const
+    {
+      return ( attachment == rhs.attachment )
+          && ( layout == rhs.layout );
+    }
+
+    bool operator!=( AttachmentReference const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t attachment;
+    ImageLayout layout;
+  };
+  static_assert( sizeof( AttachmentReference ) == sizeof( VkAttachmentReference ), "struct and wrapper have different size!" );
+
+  enum class AttachmentLoadOp
+  {
+    eLoad = VK_ATTACHMENT_LOAD_OP_LOAD,
+    eClear = VK_ATTACHMENT_LOAD_OP_CLEAR,
+    eDontCare = VK_ATTACHMENT_LOAD_OP_DONT_CARE
+  };
+
+  enum class AttachmentStoreOp
+  {
+    eStore = VK_ATTACHMENT_STORE_OP_STORE,
+    eDontCare = VK_ATTACHMENT_STORE_OP_DONT_CARE
+  };
+
+  enum class ImageType
+  {
+    e1D = VK_IMAGE_TYPE_1D,
+    e2D = VK_IMAGE_TYPE_2D,
+    e3D = VK_IMAGE_TYPE_3D
+  };
+
+  enum class ImageTiling
+  {
+    eOptimal = VK_IMAGE_TILING_OPTIMAL,
+    eLinear = VK_IMAGE_TILING_LINEAR
+  };
+
+  enum class ImageViewType
+  {
+    e1D = VK_IMAGE_VIEW_TYPE_1D,
+    e2D = VK_IMAGE_VIEW_TYPE_2D,
+    e3D = VK_IMAGE_VIEW_TYPE_3D,
+    eCube = VK_IMAGE_VIEW_TYPE_CUBE,
+    e1DArray = VK_IMAGE_VIEW_TYPE_1D_ARRAY,
+    e2DArray = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
+    eCubeArray = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
+  };
+
+  enum class CommandBufferLevel
+  {
+    ePrimary = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+    eSecondary = VK_COMMAND_BUFFER_LEVEL_SECONDARY
+  };
+
+  enum class ComponentSwizzle
+  {
+    eIdentity = VK_COMPONENT_SWIZZLE_IDENTITY,
+    eZero = VK_COMPONENT_SWIZZLE_ZERO,
+    eOne = VK_COMPONENT_SWIZZLE_ONE,
+    eR = VK_COMPONENT_SWIZZLE_R,
+    eG = VK_COMPONENT_SWIZZLE_G,
+    eB = VK_COMPONENT_SWIZZLE_B,
+    eA = VK_COMPONENT_SWIZZLE_A
+  };
+
+  struct ComponentMapping
+  {
+    ComponentMapping( ComponentSwizzle r_ = ComponentSwizzle::eIdentity, ComponentSwizzle g_ = ComponentSwizzle::eIdentity, ComponentSwizzle b_ = ComponentSwizzle::eIdentity, ComponentSwizzle a_ = ComponentSwizzle::eIdentity )
+      : r( r_ )
+      , g( g_ )
+      , b( b_ )
+      , a( a_ )
+    {
+    }
+
+    ComponentMapping( VkComponentMapping const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ComponentMapping) );
+    }
+
+    ComponentMapping& operator=( VkComponentMapping const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ComponentMapping) );
+      return *this;
+    }
+
+    ComponentMapping& setR( ComponentSwizzle r_ )
+    {
+      r = r_;
+      return *this;
+    }
+
+    ComponentMapping& setG( ComponentSwizzle g_ )
+    {
+      g = g_;
+      return *this;
+    }
+
+    ComponentMapping& setB( ComponentSwizzle b_ )
+    {
+      b = b_;
+      return *this;
+    }
+
+    ComponentMapping& setA( ComponentSwizzle a_ )
+    {
+      a = a_;
+      return *this;
+    }
+
+    operator const VkComponentMapping&() const
+    {
+      return *reinterpret_cast<const VkComponentMapping*>(this);
+    }
+
+    bool operator==( ComponentMapping const& rhs ) const
+    {
+      return ( r == rhs.r )
+          && ( g == rhs.g )
+          && ( b == rhs.b )
+          && ( a == rhs.a );
+    }
+
+    bool operator!=( ComponentMapping const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ComponentSwizzle r;
+    ComponentSwizzle g;
+    ComponentSwizzle b;
+    ComponentSwizzle a;
+  };
+  static_assert( sizeof( ComponentMapping ) == sizeof( VkComponentMapping ), "struct and wrapper have different size!" );
+
+  enum class DescriptorType
+  {
+    eSampler = VK_DESCRIPTOR_TYPE_SAMPLER,
+    eCombinedImageSampler = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+    eSampledImage = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+    eStorageImage = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
+    eUniformTexelBuffer = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
+    eStorageTexelBuffer = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
+    eUniformBuffer = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+    eStorageBuffer = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+    eUniformBufferDynamic = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
+    eStorageBufferDynamic = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC,
+    eInputAttachment = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
+  };
+
+  struct DescriptorPoolSize
+  {
+    DescriptorPoolSize( DescriptorType type_ = DescriptorType::eSampler, uint32_t descriptorCount_ = 0 )
+      : type( type_ )
+      , descriptorCount( descriptorCount_ )
+    {
+    }
+
+    DescriptorPoolSize( VkDescriptorPoolSize const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorPoolSize) );
+    }
+
+    DescriptorPoolSize& operator=( VkDescriptorPoolSize const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorPoolSize) );
+      return *this;
+    }
+
+    DescriptorPoolSize& setType( DescriptorType type_ )
+    {
+      type = type_;
+      return *this;
+    }
+
+    DescriptorPoolSize& setDescriptorCount( uint32_t descriptorCount_ )
+    {
+      descriptorCount = descriptorCount_;
+      return *this;
+    }
+
+    operator const VkDescriptorPoolSize&() const
+    {
+      return *reinterpret_cast<const VkDescriptorPoolSize*>(this);
+    }
+
+    bool operator==( DescriptorPoolSize const& rhs ) const
+    {
+      return ( type == rhs.type )
+          && ( descriptorCount == rhs.descriptorCount );
+    }
+
+    bool operator!=( DescriptorPoolSize const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DescriptorType type;
+    uint32_t descriptorCount;
+  };
+  static_assert( sizeof( DescriptorPoolSize ) == sizeof( VkDescriptorPoolSize ), "struct and wrapper have different size!" );
+
+  enum class QueryType
+  {
+    eOcclusion = VK_QUERY_TYPE_OCCLUSION,
+    ePipelineStatistics = VK_QUERY_TYPE_PIPELINE_STATISTICS,
+    eTimestamp = VK_QUERY_TYPE_TIMESTAMP
+  };
+
+  enum class BorderColor
+  {
+    eFloatTransparentBlack = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
+    eIntTransparentBlack = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK,
+    eFloatOpaqueBlack = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
+    eIntOpaqueBlack = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
+    eFloatOpaqueWhite = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
+    eIntOpaqueWhite = VK_BORDER_COLOR_INT_OPAQUE_WHITE
+  };
+
+  enum class PipelineBindPoint
+  {
+    eGraphics = VK_PIPELINE_BIND_POINT_GRAPHICS,
+    eCompute = VK_PIPELINE_BIND_POINT_COMPUTE
+  };
+
+  struct SubpassDescription
+  {
+    SubpassDescription( SubpassDescriptionFlags flags_ = SubpassDescriptionFlags(), PipelineBindPoint pipelineBindPoint_ = PipelineBindPoint::eGraphics, uint32_t inputAttachmentCount_ = 0, const AttachmentReference* pInputAttachments_ = nullptr, uint32_t colorAttachmentCount_ = 0, const AttachmentReference* pColorAttachments_ = nullptr, const AttachmentReference* pResolveAttachments_ = nullptr, const AttachmentReference* pDepthStencilAttachment_ = nullptr, uint32_t preserveAttachmentCount_ = 0, const uint32_t* pPreserveAttachments_ = nullptr )
+      : flags( flags_ )
+      , pipelineBindPoint( pipelineBindPoint_ )
+      , inputAttachmentCount( inputAttachmentCount_ )
+      , pInputAttachments( pInputAttachments_ )
+      , colorAttachmentCount( colorAttachmentCount_ )
+      , pColorAttachments( pColorAttachments_ )
+      , pResolveAttachments( pResolveAttachments_ )
+      , pDepthStencilAttachment( pDepthStencilAttachment_ )
+      , preserveAttachmentCount( preserveAttachmentCount_ )
+      , pPreserveAttachments( pPreserveAttachments_ )
+    {
+    }
+
+    SubpassDescription( VkSubpassDescription const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SubpassDescription) );
+    }
+
+    SubpassDescription& operator=( VkSubpassDescription const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SubpassDescription) );
+      return *this;
+    }
+
+    SubpassDescription& setFlags( SubpassDescriptionFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    SubpassDescription& setPipelineBindPoint( PipelineBindPoint pipelineBindPoint_ )
+    {
+      pipelineBindPoint = pipelineBindPoint_;
+      return *this;
+    }
+
+    SubpassDescription& setInputAttachmentCount( uint32_t inputAttachmentCount_ )
+    {
+      inputAttachmentCount = inputAttachmentCount_;
+      return *this;
+    }
+
+    SubpassDescription& setPInputAttachments( const AttachmentReference* pInputAttachments_ )
+    {
+      pInputAttachments = pInputAttachments_;
+      return *this;
+    }
+
+    SubpassDescription& setColorAttachmentCount( uint32_t colorAttachmentCount_ )
+    {
+      colorAttachmentCount = colorAttachmentCount_;
+      return *this;
+    }
+
+    SubpassDescription& setPColorAttachments( const AttachmentReference* pColorAttachments_ )
+    {
+      pColorAttachments = pColorAttachments_;
+      return *this;
+    }
+
+    SubpassDescription& setPResolveAttachments( const AttachmentReference* pResolveAttachments_ )
+    {
+      pResolveAttachments = pResolveAttachments_;
+      return *this;
+    }
+
+    SubpassDescription& setPDepthStencilAttachment( const AttachmentReference* pDepthStencilAttachment_ )
+    {
+      pDepthStencilAttachment = pDepthStencilAttachment_;
+      return *this;
+    }
+
+    SubpassDescription& setPreserveAttachmentCount( uint32_t preserveAttachmentCount_ )
+    {
+      preserveAttachmentCount = preserveAttachmentCount_;
+      return *this;
+    }
+
+    SubpassDescription& setPPreserveAttachments( const uint32_t* pPreserveAttachments_ )
+    {
+      pPreserveAttachments = pPreserveAttachments_;
+      return *this;
+    }
+
+    operator const VkSubpassDescription&() const
+    {
+      return *reinterpret_cast<const VkSubpassDescription*>(this);
+    }
+
+    bool operator==( SubpassDescription const& rhs ) const
+    {
+      return ( flags == rhs.flags )
+          && ( pipelineBindPoint == rhs.pipelineBindPoint )
+          && ( inputAttachmentCount == rhs.inputAttachmentCount )
+          && ( pInputAttachments == rhs.pInputAttachments )
+          && ( colorAttachmentCount == rhs.colorAttachmentCount )
+          && ( pColorAttachments == rhs.pColorAttachments )
+          && ( pResolveAttachments == rhs.pResolveAttachments )
+          && ( pDepthStencilAttachment == rhs.pDepthStencilAttachment )
+          && ( preserveAttachmentCount == rhs.preserveAttachmentCount )
+          && ( pPreserveAttachments == rhs.pPreserveAttachments );
+    }
+
+    bool operator!=( SubpassDescription const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    SubpassDescriptionFlags flags;
+    PipelineBindPoint pipelineBindPoint;
+    uint32_t inputAttachmentCount;
+    const AttachmentReference* pInputAttachments;
+    uint32_t colorAttachmentCount;
+    const AttachmentReference* pColorAttachments;
+    const AttachmentReference* pResolveAttachments;
+    const AttachmentReference* pDepthStencilAttachment;
+    uint32_t preserveAttachmentCount;
+    const uint32_t* pPreserveAttachments;
+  };
+  static_assert( sizeof( SubpassDescription ) == sizeof( VkSubpassDescription ), "struct and wrapper have different size!" );
+
+  enum class PipelineCacheHeaderVersion
+  {
+    eOne = VK_PIPELINE_CACHE_HEADER_VERSION_ONE
+  };
+
+  enum class PrimitiveTopology
+  {
+    ePointList = VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
+    eLineList = VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
+    eLineStrip = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
+    eTriangleList = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+    eTriangleStrip = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+    eTriangleFan = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
+    eLineListWithAdjacency = VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
+    eLineStripWithAdjacency = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
+    eTriangleListWithAdjacency = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
+    eTriangleStripWithAdjacency = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
+    ePatchList = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
+  };
+
+  enum class SharingMode
+  {
+    eExclusive = VK_SHARING_MODE_EXCLUSIVE,
+    eConcurrent = VK_SHARING_MODE_CONCURRENT
+  };
+
+  enum class IndexType
+  {
+    eUint16 = VK_INDEX_TYPE_UINT16,
+    eUint32 = VK_INDEX_TYPE_UINT32
+  };
+
+  enum class Filter
+  {
+    eNearest = VK_FILTER_NEAREST,
+    eLinear = VK_FILTER_LINEAR,
+    eCubicIMG = VK_FILTER_CUBIC_IMG
+  };
+
+  enum class SamplerMipmapMode
+  {
+    eNearest = VK_SAMPLER_MIPMAP_MODE_NEAREST,
+    eLinear = VK_SAMPLER_MIPMAP_MODE_LINEAR
+  };
+
+  enum class SamplerAddressMode
+  {
+    eRepeat = VK_SAMPLER_ADDRESS_MODE_REPEAT,
+    eMirroredRepeat = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,
+    eClampToEdge = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
+    eClampToBorder = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
+    eMirrorClampToEdge = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE
+  };
+
+  enum class CompareOp
+  {
+    eNever = VK_COMPARE_OP_NEVER,
+    eLess = VK_COMPARE_OP_LESS,
+    eEqual = VK_COMPARE_OP_EQUAL,
+    eLessOrEqual = VK_COMPARE_OP_LESS_OR_EQUAL,
+    eGreater = VK_COMPARE_OP_GREATER,
+    eNotEqual = VK_COMPARE_OP_NOT_EQUAL,
+    eGreaterOrEqual = VK_COMPARE_OP_GREATER_OR_EQUAL,
+    eAlways = VK_COMPARE_OP_ALWAYS
+  };
+
+  enum class PolygonMode
+  {
+    eFill = VK_POLYGON_MODE_FILL,
+    eLine = VK_POLYGON_MODE_LINE,
+    ePoint = VK_POLYGON_MODE_POINT
+  };
+
+  enum class CullModeFlagBits
+  {
+    eNone = VK_CULL_MODE_NONE,
+    eFront = VK_CULL_MODE_FRONT_BIT,
+    eBack = VK_CULL_MODE_BACK_BIT,
+    eFrontAndBack = VK_CULL_MODE_FRONT_AND_BACK
+  };
+
+  using CullModeFlags = Flags<CullModeFlagBits, VkCullModeFlags>;
+
+  inline CullModeFlags operator|( CullModeFlagBits bit0, CullModeFlagBits bit1 )
+  {
+    return CullModeFlags( bit0 ) | bit1;
+  }
+
+  enum class FrontFace
+  {
+    eCounterClockwise = VK_FRONT_FACE_COUNTER_CLOCKWISE,
+    eClockwise = VK_FRONT_FACE_CLOCKWISE
+  };
+
+  enum class BlendFactor
+  {
+    eZero = VK_BLEND_FACTOR_ZERO,
+    eOne = VK_BLEND_FACTOR_ONE,
+    eSrcColor = VK_BLEND_FACTOR_SRC_COLOR,
+    eOneMinusSrcColor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
+    eDstColor = VK_BLEND_FACTOR_DST_COLOR,
+    eOneMinusDstColor = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR,
+    eSrcAlpha = VK_BLEND_FACTOR_SRC_ALPHA,
+    eOneMinusSrcAlpha = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
+    eDstAlpha = VK_BLEND_FACTOR_DST_ALPHA,
+    eOneMinusDstAlpha = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA,
+    eConstantColor = VK_BLEND_FACTOR_CONSTANT_COLOR,
+    eOneMinusConstantColor = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
+    eConstantAlpha = VK_BLEND_FACTOR_CONSTANT_ALPHA,
+    eOneMinusConstantAlpha = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA,
+    eSrcAlphaSaturate = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE,
+    eSrc1Color = VK_BLEND_FACTOR_SRC1_COLOR,
+    eOneMinusSrc1Color = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
+    eSrc1Alpha = VK_BLEND_FACTOR_SRC1_ALPHA,
+    eOneMinusSrc1Alpha = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
+  };
+
+  enum class BlendOp
+  {
+    eAdd = VK_BLEND_OP_ADD,
+    eSubtract = VK_BLEND_OP_SUBTRACT,
+    eReverseSubtract = VK_BLEND_OP_REVERSE_SUBTRACT,
+    eMin = VK_BLEND_OP_MIN,
+    eMax = VK_BLEND_OP_MAX
+  };
+
+  enum class StencilOp
+  {
+    eKeep = VK_STENCIL_OP_KEEP,
+    eZero = VK_STENCIL_OP_ZERO,
+    eReplace = VK_STENCIL_OP_REPLACE,
+    eIncrementAndClamp = VK_STENCIL_OP_INCREMENT_AND_CLAMP,
+    eDecrementAndClamp = VK_STENCIL_OP_DECREMENT_AND_CLAMP,
+    eInvert = VK_STENCIL_OP_INVERT,
+    eIncrementAndWrap = VK_STENCIL_OP_INCREMENT_AND_WRAP,
+    eDecrementAndWrap = VK_STENCIL_OP_DECREMENT_AND_WRAP
+  };
+
+  struct StencilOpState
+  {
+    StencilOpState( StencilOp failOp_ = StencilOp::eKeep, StencilOp passOp_ = StencilOp::eKeep, StencilOp depthFailOp_ = StencilOp::eKeep, CompareOp compareOp_ = CompareOp::eNever, uint32_t compareMask_ = 0, uint32_t writeMask_ = 0, uint32_t reference_ = 0 )
+      : failOp( failOp_ )
+      , passOp( passOp_ )
+      , depthFailOp( depthFailOp_ )
+      , compareOp( compareOp_ )
+      , compareMask( compareMask_ )
+      , writeMask( writeMask_ )
+      , reference( reference_ )
+    {
+    }
+
+    StencilOpState( VkStencilOpState const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(StencilOpState) );
+    }
+
+    StencilOpState& operator=( VkStencilOpState const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(StencilOpState) );
+      return *this;
+    }
+
+    StencilOpState& setFailOp( StencilOp failOp_ )
+    {
+      failOp = failOp_;
+      return *this;
+    }
+
+    StencilOpState& setPassOp( StencilOp passOp_ )
+    {
+      passOp = passOp_;
+      return *this;
+    }
+
+    StencilOpState& setDepthFailOp( StencilOp depthFailOp_ )
+    {
+      depthFailOp = depthFailOp_;
+      return *this;
+    }
+
+    StencilOpState& setCompareOp( CompareOp compareOp_ )
+    {
+      compareOp = compareOp_;
+      return *this;
+    }
+
+    StencilOpState& setCompareMask( uint32_t compareMask_ )
+    {
+      compareMask = compareMask_;
+      return *this;
+    }
+
+    StencilOpState& setWriteMask( uint32_t writeMask_ )
+    {
+      writeMask = writeMask_;
+      return *this;
+    }
+
+    StencilOpState& setReference( uint32_t reference_ )
+    {
+      reference = reference_;
+      return *this;
+    }
+
+    operator const VkStencilOpState&() const
+    {
+      return *reinterpret_cast<const VkStencilOpState*>(this);
+    }
+
+    bool operator==( StencilOpState const& rhs ) const
+    {
+      return ( failOp == rhs.failOp )
+          && ( passOp == rhs.passOp )
+          && ( depthFailOp == rhs.depthFailOp )
+          && ( compareOp == rhs.compareOp )
+          && ( compareMask == rhs.compareMask )
+          && ( writeMask == rhs.writeMask )
+          && ( reference == rhs.reference );
+    }
+
+    bool operator!=( StencilOpState const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    StencilOp failOp;
+    StencilOp passOp;
+    StencilOp depthFailOp;
+    CompareOp compareOp;
+    uint32_t compareMask;
+    uint32_t writeMask;
+    uint32_t reference;
+  };
+  static_assert( sizeof( StencilOpState ) == sizeof( VkStencilOpState ), "struct and wrapper have different size!" );
+
+  enum class LogicOp
+  {
+    eClear = VK_LOGIC_OP_CLEAR,
+    eAnd = VK_LOGIC_OP_AND,
+    eAndReverse = VK_LOGIC_OP_AND_REVERSE,
+    eCopy = VK_LOGIC_OP_COPY,
+    eAndInverted = VK_LOGIC_OP_AND_INVERTED,
+    eNoOp = VK_LOGIC_OP_NO_OP,
+    eXor = VK_LOGIC_OP_XOR,
+    eOr = VK_LOGIC_OP_OR,
+    eNor = VK_LOGIC_OP_NOR,
+    eEquivalent = VK_LOGIC_OP_EQUIVALENT,
+    eInvert = VK_LOGIC_OP_INVERT,
+    eOrReverse = VK_LOGIC_OP_OR_REVERSE,
+    eCopyInverted = VK_LOGIC_OP_COPY_INVERTED,
+    eOrInverted = VK_LOGIC_OP_OR_INVERTED,
+    eNand = VK_LOGIC_OP_NAND,
+    eSet = VK_LOGIC_OP_SET
+  };
+
+  enum class InternalAllocationType
+  {
+    eExecutable = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE
+  };
+
+  enum class SystemAllocationScope
+  {
+    eCommand = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND,
+    eObject = VK_SYSTEM_ALLOCATION_SCOPE_OBJECT,
+    eCache = VK_SYSTEM_ALLOCATION_SCOPE_CACHE,
+    eDevice = VK_SYSTEM_ALLOCATION_SCOPE_DEVICE,
+    eInstance = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
+  };
+
+  enum class PhysicalDeviceType
+  {
+    eOther = VK_PHYSICAL_DEVICE_TYPE_OTHER,
+    eIntegratedGpu = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
+    eDiscreteGpu = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
+    eVirtualGpu = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
+    eCpu = VK_PHYSICAL_DEVICE_TYPE_CPU
+  };
+
+  enum class VertexInputRate
+  {
+    eVertex = VK_VERTEX_INPUT_RATE_VERTEX,
+    eInstance = VK_VERTEX_INPUT_RATE_INSTANCE
+  };
+
+  struct VertexInputBindingDescription
+  {
+    VertexInputBindingDescription( uint32_t binding_ = 0, uint32_t stride_ = 0, VertexInputRate inputRate_ = VertexInputRate::eVertex )
+      : binding( binding_ )
+      , stride( stride_ )
+      , inputRate( inputRate_ )
+    {
+    }
+
+    VertexInputBindingDescription( VkVertexInputBindingDescription const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(VertexInputBindingDescription) );
+    }
+
+    VertexInputBindingDescription& operator=( VkVertexInputBindingDescription const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(VertexInputBindingDescription) );
+      return *this;
+    }
+
+    VertexInputBindingDescription& setBinding( uint32_t binding_ )
+    {
+      binding = binding_;
+      return *this;
+    }
+
+    VertexInputBindingDescription& setStride( uint32_t stride_ )
+    {
+      stride = stride_;
+      return *this;
+    }
+
+    VertexInputBindingDescription& setInputRate( VertexInputRate inputRate_ )
+    {
+      inputRate = inputRate_;
+      return *this;
+    }
+
+    operator const VkVertexInputBindingDescription&() const
+    {
+      return *reinterpret_cast<const VkVertexInputBindingDescription*>(this);
+    }
+
+    bool operator==( VertexInputBindingDescription const& rhs ) const
+    {
+      return ( binding == rhs.binding )
+          && ( stride == rhs.stride )
+          && ( inputRate == rhs.inputRate );
+    }
+
+    bool operator!=( VertexInputBindingDescription const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t binding;
+    uint32_t stride;
+    VertexInputRate inputRate;
+  };
+  static_assert( sizeof( VertexInputBindingDescription ) == sizeof( VkVertexInputBindingDescription ), "struct and wrapper have different size!" );
+
+  enum class Format
+  {
+    eUndefined = VK_FORMAT_UNDEFINED,
+    eR4G4UnormPack8 = VK_FORMAT_R4G4_UNORM_PACK8,
+    eR4G4B4A4UnormPack16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16,
+    eB4G4R4A4UnormPack16 = VK_FORMAT_B4G4R4A4_UNORM_PACK16,
+    eR5G6B5UnormPack16 = VK_FORMAT_R5G6B5_UNORM_PACK16,
+    eB5G6R5UnormPack16 = VK_FORMAT_B5G6R5_UNORM_PACK16,
+    eR5G5B5A1UnormPack16 = VK_FORMAT_R5G5B5A1_UNORM_PACK16,
+    eB5G5R5A1UnormPack16 = VK_FORMAT_B5G5R5A1_UNORM_PACK16,
+    eA1R5G5B5UnormPack16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16,
+    eR8Unorm = VK_FORMAT_R8_UNORM,
+    eR8Snorm = VK_FORMAT_R8_SNORM,
+    eR8Uscaled = VK_FORMAT_R8_USCALED,
+    eR8Sscaled = VK_FORMAT_R8_SSCALED,
+    eR8Uint = VK_FORMAT_R8_UINT,
+    eR8Sint = VK_FORMAT_R8_SINT,
+    eR8Srgb = VK_FORMAT_R8_SRGB,
+    eR8G8Unorm = VK_FORMAT_R8G8_UNORM,
+    eR8G8Snorm = VK_FORMAT_R8G8_SNORM,
+    eR8G8Uscaled = VK_FORMAT_R8G8_USCALED,
+    eR8G8Sscaled = VK_FORMAT_R8G8_SSCALED,
+    eR8G8Uint = VK_FORMAT_R8G8_UINT,
+    eR8G8Sint = VK_FORMAT_R8G8_SINT,
+    eR8G8Srgb = VK_FORMAT_R8G8_SRGB,
+    eR8G8B8Unorm = VK_FORMAT_R8G8B8_UNORM,
+    eR8G8B8Snorm = VK_FORMAT_R8G8B8_SNORM,
+    eR8G8B8Uscaled = VK_FORMAT_R8G8B8_USCALED,
+    eR8G8B8Sscaled = VK_FORMAT_R8G8B8_SSCALED,
+    eR8G8B8Uint = VK_FORMAT_R8G8B8_UINT,
+    eR8G8B8Sint = VK_FORMAT_R8G8B8_SINT,
+    eR8G8B8Srgb = VK_FORMAT_R8G8B8_SRGB,
+    eB8G8R8Unorm = VK_FORMAT_B8G8R8_UNORM,
+    eB8G8R8Snorm = VK_FORMAT_B8G8R8_SNORM,
+    eB8G8R8Uscaled = VK_FORMAT_B8G8R8_USCALED,
+    eB8G8R8Sscaled = VK_FORMAT_B8G8R8_SSCALED,
+    eB8G8R8Uint = VK_FORMAT_B8G8R8_UINT,
+    eB8G8R8Sint = VK_FORMAT_B8G8R8_SINT,
+    eB8G8R8Srgb = VK_FORMAT_B8G8R8_SRGB,
+    eR8G8B8A8Unorm = VK_FORMAT_R8G8B8A8_UNORM,
+    eR8G8B8A8Snorm = VK_FORMAT_R8G8B8A8_SNORM,
+    eR8G8B8A8Uscaled = VK_FORMAT_R8G8B8A8_USCALED,
+    eR8G8B8A8Sscaled = VK_FORMAT_R8G8B8A8_SSCALED,
+    eR8G8B8A8Uint = VK_FORMAT_R8G8B8A8_UINT,
+    eR8G8B8A8Sint = VK_FORMAT_R8G8B8A8_SINT,
+    eR8G8B8A8Srgb = VK_FORMAT_R8G8B8A8_SRGB,
+    eB8G8R8A8Unorm = VK_FORMAT_B8G8R8A8_UNORM,
+    eB8G8R8A8Snorm = VK_FORMAT_B8G8R8A8_SNORM,
+    eB8G8R8A8Uscaled = VK_FORMAT_B8G8R8A8_USCALED,
+    eB8G8R8A8Sscaled = VK_FORMAT_B8G8R8A8_SSCALED,
+    eB8G8R8A8Uint = VK_FORMAT_B8G8R8A8_UINT,
+    eB8G8R8A8Sint = VK_FORMAT_B8G8R8A8_SINT,
+    eB8G8R8A8Srgb = VK_FORMAT_B8G8R8A8_SRGB,
+    eA8B8G8R8UnormPack32 = VK_FORMAT_A8B8G8R8_UNORM_PACK32,
+    eA8B8G8R8SnormPack32 = VK_FORMAT_A8B8G8R8_SNORM_PACK32,
+    eA8B8G8R8UscaledPack32 = VK_FORMAT_A8B8G8R8_USCALED_PACK32,
+    eA8B8G8R8SscaledPack32 = VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
+    eA8B8G8R8UintPack32 = VK_FORMAT_A8B8G8R8_UINT_PACK32,
+    eA8B8G8R8SintPack32 = VK_FORMAT_A8B8G8R8_SINT_PACK32,
+    eA8B8G8R8SrgbPack32 = VK_FORMAT_A8B8G8R8_SRGB_PACK32,
+    eA2R10G10B10UnormPack32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32,
+    eA2R10G10B10SnormPack32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32,
+    eA2R10G10B10UscaledPack32 = VK_FORMAT_A2R10G10B10_USCALED_PACK32,
+    eA2R10G10B10SscaledPack32 = VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
+    eA2R10G10B10UintPack32 = VK_FORMAT_A2R10G10B10_UINT_PACK32,
+    eA2R10G10B10SintPack32 = VK_FORMAT_A2R10G10B10_SINT_PACK32,
+    eA2B10G10R10UnormPack32 = VK_FORMAT_A2B10G10R10_UNORM_PACK32,
+    eA2B10G10R10SnormPack32 = VK_FORMAT_A2B10G10R10_SNORM_PACK32,
+    eA2B10G10R10UscaledPack32 = VK_FORMAT_A2B10G10R10_USCALED_PACK32,
+    eA2B10G10R10SscaledPack32 = VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
+    eA2B10G10R10UintPack32 = VK_FORMAT_A2B10G10R10_UINT_PACK32,
+    eA2B10G10R10SintPack32 = VK_FORMAT_A2B10G10R10_SINT_PACK32,
+    eR16Unorm = VK_FORMAT_R16_UNORM,
+    eR16Snorm = VK_FORMAT_R16_SNORM,
+    eR16Uscaled = VK_FORMAT_R16_USCALED,
+    eR16Sscaled = VK_FORMAT_R16_SSCALED,
+    eR16Uint = VK_FORMAT_R16_UINT,
+    eR16Sint = VK_FORMAT_R16_SINT,
+    eR16Sfloat = VK_FORMAT_R16_SFLOAT,
+    eR16G16Unorm = VK_FORMAT_R16G16_UNORM,
+    eR16G16Snorm = VK_FORMAT_R16G16_SNORM,
+    eR16G16Uscaled = VK_FORMAT_R16G16_USCALED,
+    eR16G16Sscaled = VK_FORMAT_R16G16_SSCALED,
+    eR16G16Uint = VK_FORMAT_R16G16_UINT,
+    eR16G16Sint = VK_FORMAT_R16G16_SINT,
+    eR16G16Sfloat = VK_FORMAT_R16G16_SFLOAT,
+    eR16G16B16Unorm = VK_FORMAT_R16G16B16_UNORM,
+    eR16G16B16Snorm = VK_FORMAT_R16G16B16_SNORM,
+    eR16G16B16Uscaled = VK_FORMAT_R16G16B16_USCALED,
+    eR16G16B16Sscaled = VK_FORMAT_R16G16B16_SSCALED,
+    eR16G16B16Uint = VK_FORMAT_R16G16B16_UINT,
+    eR16G16B16Sint = VK_FORMAT_R16G16B16_SINT,
+    eR16G16B16Sfloat = VK_FORMAT_R16G16B16_SFLOAT,
+    eR16G16B16A16Unorm = VK_FORMAT_R16G16B16A16_UNORM,
+    eR16G16B16A16Snorm = VK_FORMAT_R16G16B16A16_SNORM,
+    eR16G16B16A16Uscaled = VK_FORMAT_R16G16B16A16_USCALED,
+    eR16G16B16A16Sscaled = VK_FORMAT_R16G16B16A16_SSCALED,
+    eR16G16B16A16Uint = VK_FORMAT_R16G16B16A16_UINT,
+    eR16G16B16A16Sint = VK_FORMAT_R16G16B16A16_SINT,
+    eR16G16B16A16Sfloat = VK_FORMAT_R16G16B16A16_SFLOAT,
+    eR32Uint = VK_FORMAT_R32_UINT,
+    eR32Sint = VK_FORMAT_R32_SINT,
+    eR32Sfloat = VK_FORMAT_R32_SFLOAT,
+    eR32G32Uint = VK_FORMAT_R32G32_UINT,
+    eR32G32Sint = VK_FORMAT_R32G32_SINT,
+    eR32G32Sfloat = VK_FORMAT_R32G32_SFLOAT,
+    eR32G32B32Uint = VK_FORMAT_R32G32B32_UINT,
+    eR32G32B32Sint = VK_FORMAT_R32G32B32_SINT,
+    eR32G32B32Sfloat = VK_FORMAT_R32G32B32_SFLOAT,
+    eR32G32B32A32Uint = VK_FORMAT_R32G32B32A32_UINT,
+    eR32G32B32A32Sint = VK_FORMAT_R32G32B32A32_SINT,
+    eR32G32B32A32Sfloat = VK_FORMAT_R32G32B32A32_SFLOAT,
+    eR64Uint = VK_FORMAT_R64_UINT,
+    eR64Sint = VK_FORMAT_R64_SINT,
+    eR64Sfloat = VK_FORMAT_R64_SFLOAT,
+    eR64G64Uint = VK_FORMAT_R64G64_UINT,
+    eR64G64Sint = VK_FORMAT_R64G64_SINT,
+    eR64G64Sfloat = VK_FORMAT_R64G64_SFLOAT,
+    eR64G64B64Uint = VK_FORMAT_R64G64B64_UINT,
+    eR64G64B64Sint = VK_FORMAT_R64G64B64_SINT,
+    eR64G64B64Sfloat = VK_FORMAT_R64G64B64_SFLOAT,
+    eR64G64B64A64Uint = VK_FORMAT_R64G64B64A64_UINT,
+    eR64G64B64A64Sint = VK_FORMAT_R64G64B64A64_SINT,
+    eR64G64B64A64Sfloat = VK_FORMAT_R64G64B64A64_SFLOAT,
+    eB10G11R11UfloatPack32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32,
+    eE5B9G9R9UfloatPack32 = VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
+    eD16Unorm = VK_FORMAT_D16_UNORM,
+    eX8D24UnormPack32 = VK_FORMAT_X8_D24_UNORM_PACK32,
+    eD32Sfloat = VK_FORMAT_D32_SFLOAT,
+    eS8Uint = VK_FORMAT_S8_UINT,
+    eD16UnormS8Uint = VK_FORMAT_D16_UNORM_S8_UINT,
+    eD24UnormS8Uint = VK_FORMAT_D24_UNORM_S8_UINT,
+    eD32SfloatS8Uint = VK_FORMAT_D32_SFLOAT_S8_UINT,
+    eBc1RgbUnormBlock = VK_FORMAT_BC1_RGB_UNORM_BLOCK,
+    eBc1RgbSrgbBlock = VK_FORMAT_BC1_RGB_SRGB_BLOCK,
+    eBc1RgbaUnormBlock = VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
+    eBc1RgbaSrgbBlock = VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
+    eBc2UnormBlock = VK_FORMAT_BC2_UNORM_BLOCK,
+    eBc2SrgbBlock = VK_FORMAT_BC2_SRGB_BLOCK,
+    eBc3UnormBlock = VK_FORMAT_BC3_UNORM_BLOCK,
+    eBc3SrgbBlock = VK_FORMAT_BC3_SRGB_BLOCK,
+    eBc4UnormBlock = VK_FORMAT_BC4_UNORM_BLOCK,
+    eBc4SnormBlock = VK_FORMAT_BC4_SNORM_BLOCK,
+    eBc5UnormBlock = VK_FORMAT_BC5_UNORM_BLOCK,
+    eBc5SnormBlock = VK_FORMAT_BC5_SNORM_BLOCK,
+    eBc6HUfloatBlock = VK_FORMAT_BC6H_UFLOAT_BLOCK,
+    eBc6HSfloatBlock = VK_FORMAT_BC6H_SFLOAT_BLOCK,
+    eBc7UnormBlock = VK_FORMAT_BC7_UNORM_BLOCK,
+    eBc7SrgbBlock = VK_FORMAT_BC7_SRGB_BLOCK,
+    eEtc2R8G8B8UnormBlock = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
+    eEtc2R8G8B8SrgbBlock = VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
+    eEtc2R8G8B8A1UnormBlock = VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
+    eEtc2R8G8B8A1SrgbBlock = VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
+    eEtc2R8G8B8A8UnormBlock = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
+    eEtc2R8G8B8A8SrgbBlock = VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
+    eEacR11UnormBlock = VK_FORMAT_EAC_R11_UNORM_BLOCK,
+    eEacR11SnormBlock = VK_FORMAT_EAC_R11_SNORM_BLOCK,
+    eEacR11G11UnormBlock = VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
+    eEacR11G11SnormBlock = VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
+    eAstc4x4UnormBlock = VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
+    eAstc4x4SrgbBlock = VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
+    eAstc5x4UnormBlock = VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
+    eAstc5x4SrgbBlock = VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
+    eAstc5x5UnormBlock = VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
+    eAstc5x5SrgbBlock = VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
+    eAstc6x5UnormBlock = VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
+    eAstc6x5SrgbBlock = VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
+    eAstc6x6UnormBlock = VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
+    eAstc6x6SrgbBlock = VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
+    eAstc8x5UnormBlock = VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
+    eAstc8x5SrgbBlock = VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
+    eAstc8x6UnormBlock = VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
+    eAstc8x6SrgbBlock = VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
+    eAstc8x8UnormBlock = VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
+    eAstc8x8SrgbBlock = VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
+    eAstc10x5UnormBlock = VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
+    eAstc10x5SrgbBlock = VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
+    eAstc10x6UnormBlock = VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
+    eAstc10x6SrgbBlock = VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
+    eAstc10x8UnormBlock = VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
+    eAstc10x8SrgbBlock = VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
+    eAstc10x10UnormBlock = VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
+    eAstc10x10SrgbBlock = VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
+    eAstc12x10UnormBlock = VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
+    eAstc12x10SrgbBlock = VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
+    eAstc12x12UnormBlock = VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
+    eAstc12x12SrgbBlock = VK_FORMAT_ASTC_12x12_SRGB_BLOCK
+  };
+
+  struct VertexInputAttributeDescription
+  {
+    VertexInputAttributeDescription( uint32_t location_ = 0, uint32_t binding_ = 0, Format format_ = Format::eUndefined, uint32_t offset_ = 0 )
+      : location( location_ )
+      , binding( binding_ )
+      , format( format_ )
+      , offset( offset_ )
+    {
+    }
+
+    VertexInputAttributeDescription( VkVertexInputAttributeDescription const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(VertexInputAttributeDescription) );
+    }
+
+    VertexInputAttributeDescription& operator=( VkVertexInputAttributeDescription const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(VertexInputAttributeDescription) );
+      return *this;
+    }
+
+    VertexInputAttributeDescription& setLocation( uint32_t location_ )
+    {
+      location = location_;
+      return *this;
+    }
+
+    VertexInputAttributeDescription& setBinding( uint32_t binding_ )
+    {
+      binding = binding_;
+      return *this;
+    }
+
+    VertexInputAttributeDescription& setFormat( Format format_ )
+    {
+      format = format_;
+      return *this;
+    }
+
+    VertexInputAttributeDescription& setOffset( uint32_t offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    operator const VkVertexInputAttributeDescription&() const
+    {
+      return *reinterpret_cast<const VkVertexInputAttributeDescription*>(this);
+    }
+
+    bool operator==( VertexInputAttributeDescription const& rhs ) const
+    {
+      return ( location == rhs.location )
+          && ( binding == rhs.binding )
+          && ( format == rhs.format )
+          && ( offset == rhs.offset );
+    }
+
+    bool operator!=( VertexInputAttributeDescription const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t location;
+    uint32_t binding;
+    Format format;
+    uint32_t offset;
+  };
+  static_assert( sizeof( VertexInputAttributeDescription ) == sizeof( VkVertexInputAttributeDescription ), "struct and wrapper have different size!" );
+
+  enum class StructureType
+  {
+    eApplicationInfo = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+    eInstanceCreateInfo = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+    eDeviceQueueCreateInfo = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+    eDeviceCreateInfo = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+    eSubmitInfo = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+    eMemoryAllocateInfo = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+    eMappedMemoryRange = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
+    eBindSparseInfo = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,
+    eFenceCreateInfo = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+    eSemaphoreCreateInfo = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+    eEventCreateInfo = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
+    eQueryPoolCreateInfo = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
+    eBufferCreateInfo = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
+    eBufferViewCreateInfo = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
+    eImageCreateInfo = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+    eImageViewCreateInfo = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+    eShaderModuleCreateInfo = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+    ePipelineCacheCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
+    ePipelineShaderStageCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+    ePipelineVertexInputStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+    ePipelineInputAssemblyStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+    ePipelineTessellationStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
+    ePipelineViewportStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+    ePipelineRasterizationStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+    ePipelineMultisampleStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+    ePipelineDepthStencilStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+    ePipelineColorBlendStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+    ePipelineDynamicStateCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+    eGraphicsPipelineCreateInfo = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+    eComputePipelineCreateInfo = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+    ePipelineLayoutCreateInfo = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+    eSamplerCreateInfo = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
+    eDescriptorSetLayoutCreateInfo = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+    eDescriptorPoolCreateInfo = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+    eDescriptorSetAllocateInfo = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+    eWriteDescriptorSet = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+    eCopyDescriptorSet = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
+    eFramebufferCreateInfo = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+    eRenderPassCreateInfo = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+    eCommandPoolCreateInfo = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+    eCommandBufferAllocateInfo = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+    eCommandBufferInheritanceInfo = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
+    eCommandBufferBeginInfo = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+    eRenderPassBeginInfo = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+    eBufferMemoryBarrier = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
+    eImageMemoryBarrier = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+    eMemoryBarrier = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
+    eLoaderInstanceCreateInfo = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO,
+    eLoaderDeviceCreateInfo = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
+    eSwapchainCreateInfoKHR = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
+    ePresentInfoKHR = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+    eDisplayModeCreateInfoKHR = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR,
+    eDisplaySurfaceCreateInfoKHR = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR,
+    eDisplayPresentInfoKHR = VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR,
+    eXlibSurfaceCreateInfoKHR = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
+    eXcbSurfaceCreateInfoKHR = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
+    eWaylandSurfaceCreateInfoKHR = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
+    eMirSurfaceCreateInfoKHR = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR,
+    eAndroidSurfaceCreateInfoKHR = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
+    eWin32SurfaceCreateInfoKHR = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
+    eDebugReportCallbackCreateInfoEXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
+    ePipelineRasterizationStateRasterizationOrderAMD = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD,
+    eDebugMarkerObjectNameInfoEXT = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT,
+    eDebugMarkerObjectTagInfoEXT = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT,
+    eDebugMarkerMarkerInfoEXT = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT,
+    eDedicatedAllocationImageCreateInfoNV = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV,
+    eDedicatedAllocationBufferCreateInfoNV = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV,
+    eDedicatedAllocationMemoryAllocateInfoNV = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV
+  };
+
+  struct ApplicationInfo
+  {
+    ApplicationInfo( const char* pApplicationName_ = nullptr, uint32_t applicationVersion_ = 0, const char* pEngineName_ = nullptr, uint32_t engineVersion_ = 0, uint32_t apiVersion_ = 0 )
+      : sType( StructureType::eApplicationInfo )
+      , pNext( nullptr )
+      , pApplicationName( pApplicationName_ )
+      , applicationVersion( applicationVersion_ )
+      , pEngineName( pEngineName_ )
+      , engineVersion( engineVersion_ )
+      , apiVersion( apiVersion_ )
+    {
+    }
+
+    ApplicationInfo( VkApplicationInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ApplicationInfo) );
+    }
+
+    ApplicationInfo& operator=( VkApplicationInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ApplicationInfo) );
+      return *this;
+    }
+
+    ApplicationInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ApplicationInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ApplicationInfo& setPApplicationName( const char* pApplicationName_ )
+    {
+      pApplicationName = pApplicationName_;
+      return *this;
+    }
+
+    ApplicationInfo& setApplicationVersion( uint32_t applicationVersion_ )
+    {
+      applicationVersion = applicationVersion_;
+      return *this;
+    }
+
+    ApplicationInfo& setPEngineName( const char* pEngineName_ )
+    {
+      pEngineName = pEngineName_;
+      return *this;
+    }
+
+    ApplicationInfo& setEngineVersion( uint32_t engineVersion_ )
+    {
+      engineVersion = engineVersion_;
+      return *this;
+    }
+
+    ApplicationInfo& setApiVersion( uint32_t apiVersion_ )
+    {
+      apiVersion = apiVersion_;
+      return *this;
+    }
+
+    operator const VkApplicationInfo&() const
+    {
+      return *reinterpret_cast<const VkApplicationInfo*>(this);
+    }
+
+    bool operator==( ApplicationInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( pApplicationName == rhs.pApplicationName )
+          && ( applicationVersion == rhs.applicationVersion )
+          && ( pEngineName == rhs.pEngineName )
+          && ( engineVersion == rhs.engineVersion )
+          && ( apiVersion == rhs.apiVersion );
+    }
+
+    bool operator!=( ApplicationInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    const char* pApplicationName;
+    uint32_t applicationVersion;
+    const char* pEngineName;
+    uint32_t engineVersion;
+    uint32_t apiVersion;
+  };
+  static_assert( sizeof( ApplicationInfo ) == sizeof( VkApplicationInfo ), "struct and wrapper have different size!" );
+
+  struct DeviceQueueCreateInfo
+  {
+    DeviceQueueCreateInfo( DeviceQueueCreateFlags flags_ = DeviceQueueCreateFlags(), uint32_t queueFamilyIndex_ = 0, uint32_t queueCount_ = 0, const float* pQueuePriorities_ = nullptr )
+      : sType( StructureType::eDeviceQueueCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , queueFamilyIndex( queueFamilyIndex_ )
+      , queueCount( queueCount_ )
+      , pQueuePriorities( pQueuePriorities_ )
+    {
+    }
+
+    DeviceQueueCreateInfo( VkDeviceQueueCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DeviceQueueCreateInfo) );
+    }
+
+    DeviceQueueCreateInfo& operator=( VkDeviceQueueCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DeviceQueueCreateInfo) );
+      return *this;
+    }
+
+    DeviceQueueCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DeviceQueueCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DeviceQueueCreateInfo& setFlags( DeviceQueueCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    DeviceQueueCreateInfo& setQueueFamilyIndex( uint32_t queueFamilyIndex_ )
+    {
+      queueFamilyIndex = queueFamilyIndex_;
+      return *this;
+    }
+
+    DeviceQueueCreateInfo& setQueueCount( uint32_t queueCount_ )
+    {
+      queueCount = queueCount_;
+      return *this;
+    }
+
+    DeviceQueueCreateInfo& setPQueuePriorities( const float* pQueuePriorities_ )
+    {
+      pQueuePriorities = pQueuePriorities_;
+      return *this;
+    }
+
+    operator const VkDeviceQueueCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkDeviceQueueCreateInfo*>(this);
+    }
+
+    bool operator==( DeviceQueueCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( queueFamilyIndex == rhs.queueFamilyIndex )
+          && ( queueCount == rhs.queueCount )
+          && ( pQueuePriorities == rhs.pQueuePriorities );
+    }
+
+    bool operator!=( DeviceQueueCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DeviceQueueCreateFlags flags;
+    uint32_t queueFamilyIndex;
+    uint32_t queueCount;
+    const float* pQueuePriorities;
+  };
+  static_assert( sizeof( DeviceQueueCreateInfo ) == sizeof( VkDeviceQueueCreateInfo ), "struct and wrapper have different size!" );
+
+  struct DeviceCreateInfo
+  {
+    DeviceCreateInfo( DeviceCreateFlags flags_ = DeviceCreateFlags(), uint32_t queueCreateInfoCount_ = 0, const DeviceQueueCreateInfo* pQueueCreateInfos_ = nullptr, uint32_t enabledLayerCount_ = 0, const char* const* ppEnabledLayerNames_ = nullptr, uint32_t enabledExtensionCount_ = 0, const char* const* ppEnabledExtensionNames_ = nullptr, const PhysicalDeviceFeatures* pEnabledFeatures_ = nullptr )
+      : sType( StructureType::eDeviceCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , queueCreateInfoCount( queueCreateInfoCount_ )
+      , pQueueCreateInfos( pQueueCreateInfos_ )
+      , enabledLayerCount( enabledLayerCount_ )
+      , ppEnabledLayerNames( ppEnabledLayerNames_ )
+      , enabledExtensionCount( enabledExtensionCount_ )
+      , ppEnabledExtensionNames( ppEnabledExtensionNames_ )
+      , pEnabledFeatures( pEnabledFeatures_ )
+    {
+    }
+
+    DeviceCreateInfo( VkDeviceCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DeviceCreateInfo) );
+    }
+
+    DeviceCreateInfo& operator=( VkDeviceCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DeviceCreateInfo) );
+      return *this;
+    }
+
+    DeviceCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setFlags( DeviceCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setQueueCreateInfoCount( uint32_t queueCreateInfoCount_ )
+    {
+      queueCreateInfoCount = queueCreateInfoCount_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setPQueueCreateInfos( const DeviceQueueCreateInfo* pQueueCreateInfos_ )
+    {
+      pQueueCreateInfos = pQueueCreateInfos_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setEnabledLayerCount( uint32_t enabledLayerCount_ )
+    {
+      enabledLayerCount = enabledLayerCount_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setPpEnabledLayerNames( const char* const* ppEnabledLayerNames_ )
+    {
+      ppEnabledLayerNames = ppEnabledLayerNames_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setEnabledExtensionCount( uint32_t enabledExtensionCount_ )
+    {
+      enabledExtensionCount = enabledExtensionCount_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setPpEnabledExtensionNames( const char* const* ppEnabledExtensionNames_ )
+    {
+      ppEnabledExtensionNames = ppEnabledExtensionNames_;
+      return *this;
+    }
+
+    DeviceCreateInfo& setPEnabledFeatures( const PhysicalDeviceFeatures* pEnabledFeatures_ )
+    {
+      pEnabledFeatures = pEnabledFeatures_;
+      return *this;
+    }
+
+    operator const VkDeviceCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkDeviceCreateInfo*>(this);
+    }
+
+    bool operator==( DeviceCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( queueCreateInfoCount == rhs.queueCreateInfoCount )
+          && ( pQueueCreateInfos == rhs.pQueueCreateInfos )
+          && ( enabledLayerCount == rhs.enabledLayerCount )
+          && ( ppEnabledLayerNames == rhs.ppEnabledLayerNames )
+          && ( enabledExtensionCount == rhs.enabledExtensionCount )
+          && ( ppEnabledExtensionNames == rhs.ppEnabledExtensionNames )
+          && ( pEnabledFeatures == rhs.pEnabledFeatures );
+    }
+
+    bool operator!=( DeviceCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DeviceCreateFlags flags;
+    uint32_t queueCreateInfoCount;
+    const DeviceQueueCreateInfo* pQueueCreateInfos;
+    uint32_t enabledLayerCount;
+    const char* const* ppEnabledLayerNames;
+    uint32_t enabledExtensionCount;
+    const char* const* ppEnabledExtensionNames;
+    const PhysicalDeviceFeatures* pEnabledFeatures;
+  };
+  static_assert( sizeof( DeviceCreateInfo ) == sizeof( VkDeviceCreateInfo ), "struct and wrapper have different size!" );
+
+  struct InstanceCreateInfo
+  {
+    InstanceCreateInfo( InstanceCreateFlags flags_ = InstanceCreateFlags(), const ApplicationInfo* pApplicationInfo_ = nullptr, uint32_t enabledLayerCount_ = 0, const char* const* ppEnabledLayerNames_ = nullptr, uint32_t enabledExtensionCount_ = 0, const char* const* ppEnabledExtensionNames_ = nullptr )
+      : sType( StructureType::eInstanceCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , pApplicationInfo( pApplicationInfo_ )
+      , enabledLayerCount( enabledLayerCount_ )
+      , ppEnabledLayerNames( ppEnabledLayerNames_ )
+      , enabledExtensionCount( enabledExtensionCount_ )
+      , ppEnabledExtensionNames( ppEnabledExtensionNames_ )
+    {
+    }
+
+    InstanceCreateInfo( VkInstanceCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(InstanceCreateInfo) );
+    }
+
+    InstanceCreateInfo& operator=( VkInstanceCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(InstanceCreateInfo) );
+      return *this;
+    }
+
+    InstanceCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    InstanceCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    InstanceCreateInfo& setFlags( InstanceCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    InstanceCreateInfo& setPApplicationInfo( const ApplicationInfo* pApplicationInfo_ )
+    {
+      pApplicationInfo = pApplicationInfo_;
+      return *this;
+    }
+
+    InstanceCreateInfo& setEnabledLayerCount( uint32_t enabledLayerCount_ )
+    {
+      enabledLayerCount = enabledLayerCount_;
+      return *this;
+    }
+
+    InstanceCreateInfo& setPpEnabledLayerNames( const char* const* ppEnabledLayerNames_ )
+    {
+      ppEnabledLayerNames = ppEnabledLayerNames_;
+      return *this;
+    }
+
+    InstanceCreateInfo& setEnabledExtensionCount( uint32_t enabledExtensionCount_ )
+    {
+      enabledExtensionCount = enabledExtensionCount_;
+      return *this;
+    }
+
+    InstanceCreateInfo& setPpEnabledExtensionNames( const char* const* ppEnabledExtensionNames_ )
+    {
+      ppEnabledExtensionNames = ppEnabledExtensionNames_;
+      return *this;
+    }
+
+    operator const VkInstanceCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkInstanceCreateInfo*>(this);
+    }
+
+    bool operator==( InstanceCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( pApplicationInfo == rhs.pApplicationInfo )
+          && ( enabledLayerCount == rhs.enabledLayerCount )
+          && ( ppEnabledLayerNames == rhs.ppEnabledLayerNames )
+          && ( enabledExtensionCount == rhs.enabledExtensionCount )
+          && ( ppEnabledExtensionNames == rhs.ppEnabledExtensionNames );
+    }
+
+    bool operator!=( InstanceCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    InstanceCreateFlags flags;
+    const ApplicationInfo* pApplicationInfo;
+    uint32_t enabledLayerCount;
+    const char* const* ppEnabledLayerNames;
+    uint32_t enabledExtensionCount;
+    const char* const* ppEnabledExtensionNames;
+  };
+  static_assert( sizeof( InstanceCreateInfo ) == sizeof( VkInstanceCreateInfo ), "struct and wrapper have different size!" );
+
+  struct MemoryAllocateInfo
+  {
+    MemoryAllocateInfo( DeviceSize allocationSize_ = 0, uint32_t memoryTypeIndex_ = 0 )
+      : sType( StructureType::eMemoryAllocateInfo )
+      , pNext( nullptr )
+      , allocationSize( allocationSize_ )
+      , memoryTypeIndex( memoryTypeIndex_ )
+    {
+    }
+
+    MemoryAllocateInfo( VkMemoryAllocateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(MemoryAllocateInfo) );
+    }
+
+    MemoryAllocateInfo& operator=( VkMemoryAllocateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(MemoryAllocateInfo) );
+      return *this;
+    }
+
+    MemoryAllocateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    MemoryAllocateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    MemoryAllocateInfo& setAllocationSize( DeviceSize allocationSize_ )
+    {
+      allocationSize = allocationSize_;
+      return *this;
+    }
+
+    MemoryAllocateInfo& setMemoryTypeIndex( uint32_t memoryTypeIndex_ )
+    {
+      memoryTypeIndex = memoryTypeIndex_;
+      return *this;
+    }
+
+    operator const VkMemoryAllocateInfo&() const
+    {
+      return *reinterpret_cast<const VkMemoryAllocateInfo*>(this);
+    }
+
+    bool operator==( MemoryAllocateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( allocationSize == rhs.allocationSize )
+          && ( memoryTypeIndex == rhs.memoryTypeIndex );
+    }
+
+    bool operator!=( MemoryAllocateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DeviceSize allocationSize;
+    uint32_t memoryTypeIndex;
+  };
+  static_assert( sizeof( MemoryAllocateInfo ) == sizeof( VkMemoryAllocateInfo ), "struct and wrapper have different size!" );
+
+  struct MappedMemoryRange
+  {
+    MappedMemoryRange( DeviceMemory memory_ = DeviceMemory(), DeviceSize offset_ = 0, DeviceSize size_ = 0 )
+      : sType( StructureType::eMappedMemoryRange )
+      , pNext( nullptr )
+      , memory( memory_ )
+      , offset( offset_ )
+      , size( size_ )
+    {
+    }
+
+    MappedMemoryRange( VkMappedMemoryRange const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(MappedMemoryRange) );
+    }
+
+    MappedMemoryRange& operator=( VkMappedMemoryRange const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(MappedMemoryRange) );
+      return *this;
+    }
+
+    MappedMemoryRange& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    MappedMemoryRange& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    MappedMemoryRange& setMemory( DeviceMemory memory_ )
+    {
+      memory = memory_;
+      return *this;
+    }
+
+    MappedMemoryRange& setOffset( DeviceSize offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    MappedMemoryRange& setSize( DeviceSize size_ )
+    {
+      size = size_;
+      return *this;
+    }
+
+    operator const VkMappedMemoryRange&() const
+    {
+      return *reinterpret_cast<const VkMappedMemoryRange*>(this);
+    }
+
+    bool operator==( MappedMemoryRange const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( memory == rhs.memory )
+          && ( offset == rhs.offset )
+          && ( size == rhs.size );
+    }
+
+    bool operator!=( MappedMemoryRange const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DeviceMemory memory;
+    DeviceSize offset;
+    DeviceSize size;
+  };
+  static_assert( sizeof( MappedMemoryRange ) == sizeof( VkMappedMemoryRange ), "struct and wrapper have different size!" );
+
+  struct WriteDescriptorSet
+  {
+    WriteDescriptorSet( DescriptorSet dstSet_ = DescriptorSet(), uint32_t dstBinding_ = 0, uint32_t dstArrayElement_ = 0, uint32_t descriptorCount_ = 0, DescriptorType descriptorType_ = DescriptorType::eSampler, const DescriptorImageInfo* pImageInfo_ = nullptr, const DescriptorBufferInfo* pBufferInfo_ = nullptr, const BufferView* pTexelBufferView_ = nullptr )
+      : sType( StructureType::eWriteDescriptorSet )
+      , pNext( nullptr )
+      , dstSet( dstSet_ )
+      , dstBinding( dstBinding_ )
+      , dstArrayElement( dstArrayElement_ )
+      , descriptorCount( descriptorCount_ )
+      , descriptorType( descriptorType_ )
+      , pImageInfo( pImageInfo_ )
+      , pBufferInfo( pBufferInfo_ )
+      , pTexelBufferView( pTexelBufferView_ )
+    {
+    }
+
+    WriteDescriptorSet( VkWriteDescriptorSet const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(WriteDescriptorSet) );
+    }
+
+    WriteDescriptorSet& operator=( VkWriteDescriptorSet const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(WriteDescriptorSet) );
+      return *this;
+    }
+
+    WriteDescriptorSet& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setDstSet( DescriptorSet dstSet_ )
+    {
+      dstSet = dstSet_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setDstBinding( uint32_t dstBinding_ )
+    {
+      dstBinding = dstBinding_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setDstArrayElement( uint32_t dstArrayElement_ )
+    {
+      dstArrayElement = dstArrayElement_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setDescriptorCount( uint32_t descriptorCount_ )
+    {
+      descriptorCount = descriptorCount_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setDescriptorType( DescriptorType descriptorType_ )
+    {
+      descriptorType = descriptorType_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setPImageInfo( const DescriptorImageInfo* pImageInfo_ )
+    {
+      pImageInfo = pImageInfo_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setPBufferInfo( const DescriptorBufferInfo* pBufferInfo_ )
+    {
+      pBufferInfo = pBufferInfo_;
+      return *this;
+    }
+
+    WriteDescriptorSet& setPTexelBufferView( const BufferView* pTexelBufferView_ )
+    {
+      pTexelBufferView = pTexelBufferView_;
+      return *this;
+    }
+
+    operator const VkWriteDescriptorSet&() const
+    {
+      return *reinterpret_cast<const VkWriteDescriptorSet*>(this);
+    }
+
+    bool operator==( WriteDescriptorSet const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( dstSet == rhs.dstSet )
+          && ( dstBinding == rhs.dstBinding )
+          && ( dstArrayElement == rhs.dstArrayElement )
+          && ( descriptorCount == rhs.descriptorCount )
+          && ( descriptorType == rhs.descriptorType )
+          && ( pImageInfo == rhs.pImageInfo )
+          && ( pBufferInfo == rhs.pBufferInfo )
+          && ( pTexelBufferView == rhs.pTexelBufferView );
+    }
+
+    bool operator!=( WriteDescriptorSet const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DescriptorSet dstSet;
+    uint32_t dstBinding;
+    uint32_t dstArrayElement;
+    uint32_t descriptorCount;
+    DescriptorType descriptorType;
+    const DescriptorImageInfo* pImageInfo;
+    const DescriptorBufferInfo* pBufferInfo;
+    const BufferView* pTexelBufferView;
+  };
+  static_assert( sizeof( WriteDescriptorSet ) == sizeof( VkWriteDescriptorSet ), "struct and wrapper have different size!" );
+
+  struct CopyDescriptorSet
+  {
+    CopyDescriptorSet( DescriptorSet srcSet_ = DescriptorSet(), uint32_t srcBinding_ = 0, uint32_t srcArrayElement_ = 0, DescriptorSet dstSet_ = DescriptorSet(), uint32_t dstBinding_ = 0, uint32_t dstArrayElement_ = 0, uint32_t descriptorCount_ = 0 )
+      : sType( StructureType::eCopyDescriptorSet )
+      , pNext( nullptr )
+      , srcSet( srcSet_ )
+      , srcBinding( srcBinding_ )
+      , srcArrayElement( srcArrayElement_ )
+      , dstSet( dstSet_ )
+      , dstBinding( dstBinding_ )
+      , dstArrayElement( dstArrayElement_ )
+      , descriptorCount( descriptorCount_ )
+    {
+    }
+
+    CopyDescriptorSet( VkCopyDescriptorSet const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CopyDescriptorSet) );
+    }
+
+    CopyDescriptorSet& operator=( VkCopyDescriptorSet const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CopyDescriptorSet) );
+      return *this;
+    }
+
+    CopyDescriptorSet& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    CopyDescriptorSet& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    CopyDescriptorSet& setSrcSet( DescriptorSet srcSet_ )
+    {
+      srcSet = srcSet_;
+      return *this;
+    }
+
+    CopyDescriptorSet& setSrcBinding( uint32_t srcBinding_ )
+    {
+      srcBinding = srcBinding_;
+      return *this;
+    }
+
+    CopyDescriptorSet& setSrcArrayElement( uint32_t srcArrayElement_ )
+    {
+      srcArrayElement = srcArrayElement_;
+      return *this;
+    }
+
+    CopyDescriptorSet& setDstSet( DescriptorSet dstSet_ )
+    {
+      dstSet = dstSet_;
+      return *this;
+    }
+
+    CopyDescriptorSet& setDstBinding( uint32_t dstBinding_ )
+    {
+      dstBinding = dstBinding_;
+      return *this;
+    }
+
+    CopyDescriptorSet& setDstArrayElement( uint32_t dstArrayElement_ )
+    {
+      dstArrayElement = dstArrayElement_;
+      return *this;
+    }
+
+    CopyDescriptorSet& setDescriptorCount( uint32_t descriptorCount_ )
+    {
+      descriptorCount = descriptorCount_;
+      return *this;
+    }
+
+    operator const VkCopyDescriptorSet&() const
+    {
+      return *reinterpret_cast<const VkCopyDescriptorSet*>(this);
+    }
+
+    bool operator==( CopyDescriptorSet const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( srcSet == rhs.srcSet )
+          && ( srcBinding == rhs.srcBinding )
+          && ( srcArrayElement == rhs.srcArrayElement )
+          && ( dstSet == rhs.dstSet )
+          && ( dstBinding == rhs.dstBinding )
+          && ( dstArrayElement == rhs.dstArrayElement )
+          && ( descriptorCount == rhs.descriptorCount );
+    }
+
+    bool operator!=( CopyDescriptorSet const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DescriptorSet srcSet;
+    uint32_t srcBinding;
+    uint32_t srcArrayElement;
+    DescriptorSet dstSet;
+    uint32_t dstBinding;
+    uint32_t dstArrayElement;
+    uint32_t descriptorCount;
+  };
+  static_assert( sizeof( CopyDescriptorSet ) == sizeof( VkCopyDescriptorSet ), "struct and wrapper have different size!" );
+
+  struct BufferViewCreateInfo
+  {
+    BufferViewCreateInfo( BufferViewCreateFlags flags_ = BufferViewCreateFlags(), Buffer buffer_ = Buffer(), Format format_ = Format::eUndefined, DeviceSize offset_ = 0, DeviceSize range_ = 0 )
+      : sType( StructureType::eBufferViewCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , buffer( buffer_ )
+      , format( format_ )
+      , offset( offset_ )
+      , range( range_ )
+    {
+    }
+
+    BufferViewCreateInfo( VkBufferViewCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferViewCreateInfo) );
+    }
+
+    BufferViewCreateInfo& operator=( VkBufferViewCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferViewCreateInfo) );
+      return *this;
+    }
+
+    BufferViewCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    BufferViewCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    BufferViewCreateInfo& setFlags( BufferViewCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    BufferViewCreateInfo& setBuffer( Buffer buffer_ )
+    {
+      buffer = buffer_;
+      return *this;
+    }
+
+    BufferViewCreateInfo& setFormat( Format format_ )
+    {
+      format = format_;
+      return *this;
+    }
+
+    BufferViewCreateInfo& setOffset( DeviceSize offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    BufferViewCreateInfo& setRange( DeviceSize range_ )
+    {
+      range = range_;
+      return *this;
+    }
+
+    operator const VkBufferViewCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkBufferViewCreateInfo*>(this);
+    }
+
+    bool operator==( BufferViewCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( buffer == rhs.buffer )
+          && ( format == rhs.format )
+          && ( offset == rhs.offset )
+          && ( range == rhs.range );
+    }
+
+    bool operator!=( BufferViewCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    BufferViewCreateFlags flags;
+    Buffer buffer;
+    Format format;
+    DeviceSize offset;
+    DeviceSize range;
+  };
+  static_assert( sizeof( BufferViewCreateInfo ) == sizeof( VkBufferViewCreateInfo ), "struct and wrapper have different size!" );
+
+  struct ShaderModuleCreateInfo
+  {
+    ShaderModuleCreateInfo( ShaderModuleCreateFlags flags_ = ShaderModuleCreateFlags(), size_t codeSize_ = 0, const uint32_t* pCode_ = nullptr )
+      : sType( StructureType::eShaderModuleCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , codeSize( codeSize_ )
+      , pCode( pCode_ )
+    {
+    }
+
+    ShaderModuleCreateInfo( VkShaderModuleCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ShaderModuleCreateInfo) );
+    }
+
+    ShaderModuleCreateInfo& operator=( VkShaderModuleCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ShaderModuleCreateInfo) );
+      return *this;
+    }
+
+    ShaderModuleCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ShaderModuleCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ShaderModuleCreateInfo& setFlags( ShaderModuleCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    ShaderModuleCreateInfo& setCodeSize( size_t codeSize_ )
+    {
+      codeSize = codeSize_;
+      return *this;
+    }
+
+    ShaderModuleCreateInfo& setPCode( const uint32_t* pCode_ )
+    {
+      pCode = pCode_;
+      return *this;
+    }
+
+    operator const VkShaderModuleCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkShaderModuleCreateInfo*>(this);
+    }
+
+    bool operator==( ShaderModuleCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( codeSize == rhs.codeSize )
+          && ( pCode == rhs.pCode );
+    }
+
+    bool operator!=( ShaderModuleCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    ShaderModuleCreateFlags flags;
+    size_t codeSize;
+    const uint32_t* pCode;
+  };
+  static_assert( sizeof( ShaderModuleCreateInfo ) == sizeof( VkShaderModuleCreateInfo ), "struct and wrapper have different size!" );
+
+  struct DescriptorSetAllocateInfo
+  {
+    DescriptorSetAllocateInfo( DescriptorPool descriptorPool_ = DescriptorPool(), uint32_t descriptorSetCount_ = 0, const DescriptorSetLayout* pSetLayouts_ = nullptr )
+      : sType( StructureType::eDescriptorSetAllocateInfo )
+      , pNext( nullptr )
+      , descriptorPool( descriptorPool_ )
+      , descriptorSetCount( descriptorSetCount_ )
+      , pSetLayouts( pSetLayouts_ )
+    {
+    }
+
+    DescriptorSetAllocateInfo( VkDescriptorSetAllocateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorSetAllocateInfo) );
+    }
+
+    DescriptorSetAllocateInfo& operator=( VkDescriptorSetAllocateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorSetAllocateInfo) );
+      return *this;
+    }
+
+    DescriptorSetAllocateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DescriptorSetAllocateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DescriptorSetAllocateInfo& setDescriptorPool( DescriptorPool descriptorPool_ )
+    {
+      descriptorPool = descriptorPool_;
+      return *this;
+    }
+
+    DescriptorSetAllocateInfo& setDescriptorSetCount( uint32_t descriptorSetCount_ )
+    {
+      descriptorSetCount = descriptorSetCount_;
+      return *this;
+    }
+
+    DescriptorSetAllocateInfo& setPSetLayouts( const DescriptorSetLayout* pSetLayouts_ )
+    {
+      pSetLayouts = pSetLayouts_;
+      return *this;
+    }
+
+    operator const VkDescriptorSetAllocateInfo&() const
+    {
+      return *reinterpret_cast<const VkDescriptorSetAllocateInfo*>(this);
+    }
+
+    bool operator==( DescriptorSetAllocateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( descriptorPool == rhs.descriptorPool )
+          && ( descriptorSetCount == rhs.descriptorSetCount )
+          && ( pSetLayouts == rhs.pSetLayouts );
+    }
+
+    bool operator!=( DescriptorSetAllocateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DescriptorPool descriptorPool;
+    uint32_t descriptorSetCount;
+    const DescriptorSetLayout* pSetLayouts;
+  };
+  static_assert( sizeof( DescriptorSetAllocateInfo ) == sizeof( VkDescriptorSetAllocateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineVertexInputStateCreateInfo
+  {
+    PipelineVertexInputStateCreateInfo( PipelineVertexInputStateCreateFlags flags_ = PipelineVertexInputStateCreateFlags(), uint32_t vertexBindingDescriptionCount_ = 0, const VertexInputBindingDescription* pVertexBindingDescriptions_ = nullptr, uint32_t vertexAttributeDescriptionCount_ = 0, const VertexInputAttributeDescription* pVertexAttributeDescriptions_ = nullptr )
+      : sType( StructureType::ePipelineVertexInputStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , vertexBindingDescriptionCount( vertexBindingDescriptionCount_ )
+      , pVertexBindingDescriptions( pVertexBindingDescriptions_ )
+      , vertexAttributeDescriptionCount( vertexAttributeDescriptionCount_ )
+      , pVertexAttributeDescriptions( pVertexAttributeDescriptions_ )
+    {
+    }
+
+    PipelineVertexInputStateCreateInfo( VkPipelineVertexInputStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineVertexInputStateCreateInfo) );
+    }
+
+    PipelineVertexInputStateCreateInfo& operator=( VkPipelineVertexInputStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineVertexInputStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineVertexInputStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineVertexInputStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineVertexInputStateCreateInfo& setFlags( PipelineVertexInputStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineVertexInputStateCreateInfo& setVertexBindingDescriptionCount( uint32_t vertexBindingDescriptionCount_ )
+    {
+      vertexBindingDescriptionCount = vertexBindingDescriptionCount_;
+      return *this;
+    }
+
+    PipelineVertexInputStateCreateInfo& setPVertexBindingDescriptions( const VertexInputBindingDescription* pVertexBindingDescriptions_ )
+    {
+      pVertexBindingDescriptions = pVertexBindingDescriptions_;
+      return *this;
+    }
+
+    PipelineVertexInputStateCreateInfo& setVertexAttributeDescriptionCount( uint32_t vertexAttributeDescriptionCount_ )
+    {
+      vertexAttributeDescriptionCount = vertexAttributeDescriptionCount_;
+      return *this;
+    }
+
+    PipelineVertexInputStateCreateInfo& setPVertexAttributeDescriptions( const VertexInputAttributeDescription* pVertexAttributeDescriptions_ )
+    {
+      pVertexAttributeDescriptions = pVertexAttributeDescriptions_;
+      return *this;
+    }
+
+    operator const VkPipelineVertexInputStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineVertexInputStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineVertexInputStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( vertexBindingDescriptionCount == rhs.vertexBindingDescriptionCount )
+          && ( pVertexBindingDescriptions == rhs.pVertexBindingDescriptions )
+          && ( vertexAttributeDescriptionCount == rhs.vertexAttributeDescriptionCount )
+          && ( pVertexAttributeDescriptions == rhs.pVertexAttributeDescriptions );
+    }
+
+    bool operator!=( PipelineVertexInputStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineVertexInputStateCreateFlags flags;
+    uint32_t vertexBindingDescriptionCount;
+    const VertexInputBindingDescription* pVertexBindingDescriptions;
+    uint32_t vertexAttributeDescriptionCount;
+    const VertexInputAttributeDescription* pVertexAttributeDescriptions;
+  };
+  static_assert( sizeof( PipelineVertexInputStateCreateInfo ) == sizeof( VkPipelineVertexInputStateCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineInputAssemblyStateCreateInfo
+  {
+    PipelineInputAssemblyStateCreateInfo( PipelineInputAssemblyStateCreateFlags flags_ = PipelineInputAssemblyStateCreateFlags(), PrimitiveTopology topology_ = PrimitiveTopology::ePointList, Bool32 primitiveRestartEnable_ = 0 )
+      : sType( StructureType::ePipelineInputAssemblyStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , topology( topology_ )
+      , primitiveRestartEnable( primitiveRestartEnable_ )
+    {
+    }
+
+    PipelineInputAssemblyStateCreateInfo( VkPipelineInputAssemblyStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineInputAssemblyStateCreateInfo) );
+    }
+
+    PipelineInputAssemblyStateCreateInfo& operator=( VkPipelineInputAssemblyStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineInputAssemblyStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineInputAssemblyStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineInputAssemblyStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineInputAssemblyStateCreateInfo& setFlags( PipelineInputAssemblyStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineInputAssemblyStateCreateInfo& setTopology( PrimitiveTopology topology_ )
+    {
+      topology = topology_;
+      return *this;
+    }
+
+    PipelineInputAssemblyStateCreateInfo& setPrimitiveRestartEnable( Bool32 primitiveRestartEnable_ )
+    {
+      primitiveRestartEnable = primitiveRestartEnable_;
+      return *this;
+    }
+
+    operator const VkPipelineInputAssemblyStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineInputAssemblyStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineInputAssemblyStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( topology == rhs.topology )
+          && ( primitiveRestartEnable == rhs.primitiveRestartEnable );
+    }
+
+    bool operator!=( PipelineInputAssemblyStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineInputAssemblyStateCreateFlags flags;
+    PrimitiveTopology topology;
+    Bool32 primitiveRestartEnable;
+  };
+  static_assert( sizeof( PipelineInputAssemblyStateCreateInfo ) == sizeof( VkPipelineInputAssemblyStateCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineTessellationStateCreateInfo
+  {
+    PipelineTessellationStateCreateInfo( PipelineTessellationStateCreateFlags flags_ = PipelineTessellationStateCreateFlags(), uint32_t patchControlPoints_ = 0 )
+      : sType( StructureType::ePipelineTessellationStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , patchControlPoints( patchControlPoints_ )
+    {
+    }
+
+    PipelineTessellationStateCreateInfo( VkPipelineTessellationStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineTessellationStateCreateInfo) );
+    }
+
+    PipelineTessellationStateCreateInfo& operator=( VkPipelineTessellationStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineTessellationStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineTessellationStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineTessellationStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineTessellationStateCreateInfo& setFlags( PipelineTessellationStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineTessellationStateCreateInfo& setPatchControlPoints( uint32_t patchControlPoints_ )
+    {
+      patchControlPoints = patchControlPoints_;
+      return *this;
+    }
+
+    operator const VkPipelineTessellationStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineTessellationStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineTessellationStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( patchControlPoints == rhs.patchControlPoints );
+    }
+
+    bool operator!=( PipelineTessellationStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineTessellationStateCreateFlags flags;
+    uint32_t patchControlPoints;
+  };
+  static_assert( sizeof( PipelineTessellationStateCreateInfo ) == sizeof( VkPipelineTessellationStateCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineViewportStateCreateInfo
+  {
+    PipelineViewportStateCreateInfo( PipelineViewportStateCreateFlags flags_ = PipelineViewportStateCreateFlags(), uint32_t viewportCount_ = 0, const Viewport* pViewports_ = nullptr, uint32_t scissorCount_ = 0, const Rect2D* pScissors_ = nullptr )
+      : sType( StructureType::ePipelineViewportStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , viewportCount( viewportCount_ )
+      , pViewports( pViewports_ )
+      , scissorCount( scissorCount_ )
+      , pScissors( pScissors_ )
+    {
+    }
+
+    PipelineViewportStateCreateInfo( VkPipelineViewportStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineViewportStateCreateInfo) );
+    }
+
+    PipelineViewportStateCreateInfo& operator=( VkPipelineViewportStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineViewportStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineViewportStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineViewportStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineViewportStateCreateInfo& setFlags( PipelineViewportStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineViewportStateCreateInfo& setViewportCount( uint32_t viewportCount_ )
+    {
+      viewportCount = viewportCount_;
+      return *this;
+    }
+
+    PipelineViewportStateCreateInfo& setPViewports( const Viewport* pViewports_ )
+    {
+      pViewports = pViewports_;
+      return *this;
+    }
+
+    PipelineViewportStateCreateInfo& setScissorCount( uint32_t scissorCount_ )
+    {
+      scissorCount = scissorCount_;
+      return *this;
+    }
+
+    PipelineViewportStateCreateInfo& setPScissors( const Rect2D* pScissors_ )
+    {
+      pScissors = pScissors_;
+      return *this;
+    }
+
+    operator const VkPipelineViewportStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineViewportStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineViewportStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( viewportCount == rhs.viewportCount )
+          && ( pViewports == rhs.pViewports )
+          && ( scissorCount == rhs.scissorCount )
+          && ( pScissors == rhs.pScissors );
+    }
+
+    bool operator!=( PipelineViewportStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineViewportStateCreateFlags flags;
+    uint32_t viewportCount;
+    const Viewport* pViewports;
+    uint32_t scissorCount;
+    const Rect2D* pScissors;
+  };
+  static_assert( sizeof( PipelineViewportStateCreateInfo ) == sizeof( VkPipelineViewportStateCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineRasterizationStateCreateInfo
+  {
+    PipelineRasterizationStateCreateInfo( PipelineRasterizationStateCreateFlags flags_ = PipelineRasterizationStateCreateFlags(), Bool32 depthClampEnable_ = 0, Bool32 rasterizerDiscardEnable_ = 0, PolygonMode polygonMode_ = PolygonMode::eFill, CullModeFlags cullMode_ = CullModeFlags(), FrontFace frontFace_ = FrontFace::eCounterClockwise, Bool32 depthBiasEnable_ = 0, float depthBiasConstantFactor_ = 0, float depthBiasClamp_ = 0, float depthBiasSlopeFactor_ = 0, float lineWidth_ = 0 )
+      : sType( StructureType::ePipelineRasterizationStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , depthClampEnable( depthClampEnable_ )
+      , rasterizerDiscardEnable( rasterizerDiscardEnable_ )
+      , polygonMode( polygonMode_ )
+      , cullMode( cullMode_ )
+      , frontFace( frontFace_ )
+      , depthBiasEnable( depthBiasEnable_ )
+      , depthBiasConstantFactor( depthBiasConstantFactor_ )
+      , depthBiasClamp( depthBiasClamp_ )
+      , depthBiasSlopeFactor( depthBiasSlopeFactor_ )
+      , lineWidth( lineWidth_ )
+    {
+    }
+
+    PipelineRasterizationStateCreateInfo( VkPipelineRasterizationStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineRasterizationStateCreateInfo) );
+    }
+
+    PipelineRasterizationStateCreateInfo& operator=( VkPipelineRasterizationStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineRasterizationStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setFlags( PipelineRasterizationStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setDepthClampEnable( Bool32 depthClampEnable_ )
+    {
+      depthClampEnable = depthClampEnable_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setRasterizerDiscardEnable( Bool32 rasterizerDiscardEnable_ )
+    {
+      rasterizerDiscardEnable = rasterizerDiscardEnable_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setPolygonMode( PolygonMode polygonMode_ )
+    {
+      polygonMode = polygonMode_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setCullMode( CullModeFlags cullMode_ )
+    {
+      cullMode = cullMode_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setFrontFace( FrontFace frontFace_ )
+    {
+      frontFace = frontFace_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setDepthBiasEnable( Bool32 depthBiasEnable_ )
+    {
+      depthBiasEnable = depthBiasEnable_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setDepthBiasConstantFactor( float depthBiasConstantFactor_ )
+    {
+      depthBiasConstantFactor = depthBiasConstantFactor_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setDepthBiasClamp( float depthBiasClamp_ )
+    {
+      depthBiasClamp = depthBiasClamp_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setDepthBiasSlopeFactor( float depthBiasSlopeFactor_ )
+    {
+      depthBiasSlopeFactor = depthBiasSlopeFactor_;
+      return *this;
+    }
+
+    PipelineRasterizationStateCreateInfo& setLineWidth( float lineWidth_ )
+    {
+      lineWidth = lineWidth_;
+      return *this;
+    }
+
+    operator const VkPipelineRasterizationStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineRasterizationStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineRasterizationStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( depthClampEnable == rhs.depthClampEnable )
+          && ( rasterizerDiscardEnable == rhs.rasterizerDiscardEnable )
+          && ( polygonMode == rhs.polygonMode )
+          && ( cullMode == rhs.cullMode )
+          && ( frontFace == rhs.frontFace )
+          && ( depthBiasEnable == rhs.depthBiasEnable )
+          && ( depthBiasConstantFactor == rhs.depthBiasConstantFactor )
+          && ( depthBiasClamp == rhs.depthBiasClamp )
+          && ( depthBiasSlopeFactor == rhs.depthBiasSlopeFactor )
+          && ( lineWidth == rhs.lineWidth );
+    }
+
+    bool operator!=( PipelineRasterizationStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineRasterizationStateCreateFlags flags;
+    Bool32 depthClampEnable;
+    Bool32 rasterizerDiscardEnable;
+    PolygonMode polygonMode;
+    CullModeFlags cullMode;
+    FrontFace frontFace;
+    Bool32 depthBiasEnable;
+    float depthBiasConstantFactor;
+    float depthBiasClamp;
+    float depthBiasSlopeFactor;
+    float lineWidth;
+  };
+  static_assert( sizeof( PipelineRasterizationStateCreateInfo ) == sizeof( VkPipelineRasterizationStateCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineDepthStencilStateCreateInfo
+  {
+    PipelineDepthStencilStateCreateInfo( PipelineDepthStencilStateCreateFlags flags_ = PipelineDepthStencilStateCreateFlags(), Bool32 depthTestEnable_ = 0, Bool32 depthWriteEnable_ = 0, CompareOp depthCompareOp_ = CompareOp::eNever, Bool32 depthBoundsTestEnable_ = 0, Bool32 stencilTestEnable_ = 0, StencilOpState front_ = StencilOpState(), StencilOpState back_ = StencilOpState(), float minDepthBounds_ = 0, float maxDepthBounds_ = 0 )
+      : sType( StructureType::ePipelineDepthStencilStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , depthTestEnable( depthTestEnable_ )
+      , depthWriteEnable( depthWriteEnable_ )
+      , depthCompareOp( depthCompareOp_ )
+      , depthBoundsTestEnable( depthBoundsTestEnable_ )
+      , stencilTestEnable( stencilTestEnable_ )
+      , front( front_ )
+      , back( back_ )
+      , minDepthBounds( minDepthBounds_ )
+      , maxDepthBounds( maxDepthBounds_ )
+    {
+    }
+
+    PipelineDepthStencilStateCreateInfo( VkPipelineDepthStencilStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineDepthStencilStateCreateInfo) );
+    }
+
+    PipelineDepthStencilStateCreateInfo& operator=( VkPipelineDepthStencilStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineDepthStencilStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setFlags( PipelineDepthStencilStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setDepthTestEnable( Bool32 depthTestEnable_ )
+    {
+      depthTestEnable = depthTestEnable_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setDepthWriteEnable( Bool32 depthWriteEnable_ )
+    {
+      depthWriteEnable = depthWriteEnable_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setDepthCompareOp( CompareOp depthCompareOp_ )
+    {
+      depthCompareOp = depthCompareOp_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setDepthBoundsTestEnable( Bool32 depthBoundsTestEnable_ )
+    {
+      depthBoundsTestEnable = depthBoundsTestEnable_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setStencilTestEnable( Bool32 stencilTestEnable_ )
+    {
+      stencilTestEnable = stencilTestEnable_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setFront( StencilOpState front_ )
+    {
+      front = front_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setBack( StencilOpState back_ )
+    {
+      back = back_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setMinDepthBounds( float minDepthBounds_ )
+    {
+      minDepthBounds = minDepthBounds_;
+      return *this;
+    }
+
+    PipelineDepthStencilStateCreateInfo& setMaxDepthBounds( float maxDepthBounds_ )
+    {
+      maxDepthBounds = maxDepthBounds_;
+      return *this;
+    }
+
+    operator const VkPipelineDepthStencilStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineDepthStencilStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( depthTestEnable == rhs.depthTestEnable )
+          && ( depthWriteEnable == rhs.depthWriteEnable )
+          && ( depthCompareOp == rhs.depthCompareOp )
+          && ( depthBoundsTestEnable == rhs.depthBoundsTestEnable )
+          && ( stencilTestEnable == rhs.stencilTestEnable )
+          && ( front == rhs.front )
+          && ( back == rhs.back )
+          && ( minDepthBounds == rhs.minDepthBounds )
+          && ( maxDepthBounds == rhs.maxDepthBounds );
+    }
+
+    bool operator!=( PipelineDepthStencilStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineDepthStencilStateCreateFlags flags;
+    Bool32 depthTestEnable;
+    Bool32 depthWriteEnable;
+    CompareOp depthCompareOp;
+    Bool32 depthBoundsTestEnable;
+    Bool32 stencilTestEnable;
+    StencilOpState front;
+    StencilOpState back;
+    float minDepthBounds;
+    float maxDepthBounds;
+  };
+  static_assert( sizeof( PipelineDepthStencilStateCreateInfo ) == sizeof( VkPipelineDepthStencilStateCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineCacheCreateInfo
+  {
+    PipelineCacheCreateInfo( PipelineCacheCreateFlags flags_ = PipelineCacheCreateFlags(), size_t initialDataSize_ = 0, const void* pInitialData_ = nullptr )
+      : sType( StructureType::ePipelineCacheCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , initialDataSize( initialDataSize_ )
+      , pInitialData( pInitialData_ )
+    {
+    }
+
+    PipelineCacheCreateInfo( VkPipelineCacheCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineCacheCreateInfo) );
+    }
+
+    PipelineCacheCreateInfo& operator=( VkPipelineCacheCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineCacheCreateInfo) );
+      return *this;
+    }
+
+    PipelineCacheCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineCacheCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineCacheCreateInfo& setFlags( PipelineCacheCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineCacheCreateInfo& setInitialDataSize( size_t initialDataSize_ )
+    {
+      initialDataSize = initialDataSize_;
+      return *this;
+    }
+
+    PipelineCacheCreateInfo& setPInitialData( const void* pInitialData_ )
+    {
+      pInitialData = pInitialData_;
+      return *this;
+    }
+
+    operator const VkPipelineCacheCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineCacheCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineCacheCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( initialDataSize == rhs.initialDataSize )
+          && ( pInitialData == rhs.pInitialData );
+    }
+
+    bool operator!=( PipelineCacheCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineCacheCreateFlags flags;
+    size_t initialDataSize;
+    const void* pInitialData;
+  };
+  static_assert( sizeof( PipelineCacheCreateInfo ) == sizeof( VkPipelineCacheCreateInfo ), "struct and wrapper have different size!" );
+
+  struct SamplerCreateInfo
+  {
+    SamplerCreateInfo( SamplerCreateFlags flags_ = SamplerCreateFlags(), Filter magFilter_ = Filter::eNearest, Filter minFilter_ = Filter::eNearest, SamplerMipmapMode mipmapMode_ = SamplerMipmapMode::eNearest, SamplerAddressMode addressModeU_ = SamplerAddressMode::eRepeat, SamplerAddressMode addressModeV_ = SamplerAddressMode::eRepeat, SamplerAddressMode addressModeW_ = SamplerAddressMode::eRepeat, float mipLodBias_ = 0, Bool32 anisotropyEnable_ = 0, float maxAnisotropy_ = 0, Bool32 compareEnable_ = 0, CompareOp compareOp_ = CompareOp::eNever, float minLod_ = 0, float maxLod_ = 0, BorderColor borderColor_ = BorderColor::eFloatTransparentBlack, Bool32 unnormalizedCoordinates_ = 0 )
+      : sType( StructureType::eSamplerCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , magFilter( magFilter_ )
+      , minFilter( minFilter_ )
+      , mipmapMode( mipmapMode_ )
+      , addressModeU( addressModeU_ )
+      , addressModeV( addressModeV_ )
+      , addressModeW( addressModeW_ )
+      , mipLodBias( mipLodBias_ )
+      , anisotropyEnable( anisotropyEnable_ )
+      , maxAnisotropy( maxAnisotropy_ )
+      , compareEnable( compareEnable_ )
+      , compareOp( compareOp_ )
+      , minLod( minLod_ )
+      , maxLod( maxLod_ )
+      , borderColor( borderColor_ )
+      , unnormalizedCoordinates( unnormalizedCoordinates_ )
+    {
+    }
+
+    SamplerCreateInfo( VkSamplerCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SamplerCreateInfo) );
+    }
+
+    SamplerCreateInfo& operator=( VkSamplerCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SamplerCreateInfo) );
+      return *this;
+    }
+
+    SamplerCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setFlags( SamplerCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setMagFilter( Filter magFilter_ )
+    {
+      magFilter = magFilter_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setMinFilter( Filter minFilter_ )
+    {
+      minFilter = minFilter_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setMipmapMode( SamplerMipmapMode mipmapMode_ )
+    {
+      mipmapMode = mipmapMode_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setAddressModeU( SamplerAddressMode addressModeU_ )
+    {
+      addressModeU = addressModeU_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setAddressModeV( SamplerAddressMode addressModeV_ )
+    {
+      addressModeV = addressModeV_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setAddressModeW( SamplerAddressMode addressModeW_ )
+    {
+      addressModeW = addressModeW_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setMipLodBias( float mipLodBias_ )
+    {
+      mipLodBias = mipLodBias_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setAnisotropyEnable( Bool32 anisotropyEnable_ )
+    {
+      anisotropyEnable = anisotropyEnable_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setMaxAnisotropy( float maxAnisotropy_ )
+    {
+      maxAnisotropy = maxAnisotropy_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setCompareEnable( Bool32 compareEnable_ )
+    {
+      compareEnable = compareEnable_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setCompareOp( CompareOp compareOp_ )
+    {
+      compareOp = compareOp_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setMinLod( float minLod_ )
+    {
+      minLod = minLod_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setMaxLod( float maxLod_ )
+    {
+      maxLod = maxLod_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setBorderColor( BorderColor borderColor_ )
+    {
+      borderColor = borderColor_;
+      return *this;
+    }
+
+    SamplerCreateInfo& setUnnormalizedCoordinates( Bool32 unnormalizedCoordinates_ )
+    {
+      unnormalizedCoordinates = unnormalizedCoordinates_;
+      return *this;
+    }
+
+    operator const VkSamplerCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkSamplerCreateInfo*>(this);
+    }
+
+    bool operator==( SamplerCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( magFilter == rhs.magFilter )
+          && ( minFilter == rhs.minFilter )
+          && ( mipmapMode == rhs.mipmapMode )
+          && ( addressModeU == rhs.addressModeU )
+          && ( addressModeV == rhs.addressModeV )
+          && ( addressModeW == rhs.addressModeW )
+          && ( mipLodBias == rhs.mipLodBias )
+          && ( anisotropyEnable == rhs.anisotropyEnable )
+          && ( maxAnisotropy == rhs.maxAnisotropy )
+          && ( compareEnable == rhs.compareEnable )
+          && ( compareOp == rhs.compareOp )
+          && ( minLod == rhs.minLod )
+          && ( maxLod == rhs.maxLod )
+          && ( borderColor == rhs.borderColor )
+          && ( unnormalizedCoordinates == rhs.unnormalizedCoordinates );
+    }
+
+    bool operator!=( SamplerCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    SamplerCreateFlags flags;
+    Filter magFilter;
+    Filter minFilter;
+    SamplerMipmapMode mipmapMode;
+    SamplerAddressMode addressModeU;
+    SamplerAddressMode addressModeV;
+    SamplerAddressMode addressModeW;
+    float mipLodBias;
+    Bool32 anisotropyEnable;
+    float maxAnisotropy;
+    Bool32 compareEnable;
+    CompareOp compareOp;
+    float minLod;
+    float maxLod;
+    BorderColor borderColor;
+    Bool32 unnormalizedCoordinates;
+  };
+  static_assert( sizeof( SamplerCreateInfo ) == sizeof( VkSamplerCreateInfo ), "struct and wrapper have different size!" );
+
+  struct CommandBufferAllocateInfo
+  {
+    CommandBufferAllocateInfo( CommandPool commandPool_ = CommandPool(), CommandBufferLevel level_ = CommandBufferLevel::ePrimary, uint32_t commandBufferCount_ = 0 )
+      : sType( StructureType::eCommandBufferAllocateInfo )
+      , pNext( nullptr )
+      , commandPool( commandPool_ )
+      , level( level_ )
+      , commandBufferCount( commandBufferCount_ )
+    {
+    }
+
+    CommandBufferAllocateInfo( VkCommandBufferAllocateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CommandBufferAllocateInfo) );
+    }
+
+    CommandBufferAllocateInfo& operator=( VkCommandBufferAllocateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CommandBufferAllocateInfo) );
+      return *this;
+    }
+
+    CommandBufferAllocateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    CommandBufferAllocateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    CommandBufferAllocateInfo& setCommandPool( CommandPool commandPool_ )
+    {
+      commandPool = commandPool_;
+      return *this;
+    }
+
+    CommandBufferAllocateInfo& setLevel( CommandBufferLevel level_ )
+    {
+      level = level_;
+      return *this;
+    }
+
+    CommandBufferAllocateInfo& setCommandBufferCount( uint32_t commandBufferCount_ )
+    {
+      commandBufferCount = commandBufferCount_;
+      return *this;
+    }
+
+    operator const VkCommandBufferAllocateInfo&() const
+    {
+      return *reinterpret_cast<const VkCommandBufferAllocateInfo*>(this);
+    }
+
+    bool operator==( CommandBufferAllocateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( commandPool == rhs.commandPool )
+          && ( level == rhs.level )
+          && ( commandBufferCount == rhs.commandBufferCount );
+    }
+
+    bool operator!=( CommandBufferAllocateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    CommandPool commandPool;
+    CommandBufferLevel level;
+    uint32_t commandBufferCount;
+  };
+  static_assert( sizeof( CommandBufferAllocateInfo ) == sizeof( VkCommandBufferAllocateInfo ), "struct and wrapper have different size!" );
+
+  struct RenderPassBeginInfo
+  {
+    RenderPassBeginInfo( RenderPass renderPass_ = RenderPass(), Framebuffer framebuffer_ = Framebuffer(), Rect2D renderArea_ = Rect2D(), uint32_t clearValueCount_ = 0, const ClearValue* pClearValues_ = nullptr )
+      : sType( StructureType::eRenderPassBeginInfo )
+      , pNext( nullptr )
+      , renderPass( renderPass_ )
+      , framebuffer( framebuffer_ )
+      , renderArea( renderArea_ )
+      , clearValueCount( clearValueCount_ )
+      , pClearValues( pClearValues_ )
+    {
+    }
+
+    RenderPassBeginInfo( VkRenderPassBeginInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(RenderPassBeginInfo) );
+    }
+
+    RenderPassBeginInfo& operator=( VkRenderPassBeginInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(RenderPassBeginInfo) );
+      return *this;
+    }
+
+    RenderPassBeginInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    RenderPassBeginInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    RenderPassBeginInfo& setRenderPass( RenderPass renderPass_ )
+    {
+      renderPass = renderPass_;
+      return *this;
+    }
+
+    RenderPassBeginInfo& setFramebuffer( Framebuffer framebuffer_ )
+    {
+      framebuffer = framebuffer_;
+      return *this;
+    }
+
+    RenderPassBeginInfo& setRenderArea( Rect2D renderArea_ )
+    {
+      renderArea = renderArea_;
+      return *this;
+    }
+
+    RenderPassBeginInfo& setClearValueCount( uint32_t clearValueCount_ )
+    {
+      clearValueCount = clearValueCount_;
+      return *this;
+    }
+
+    RenderPassBeginInfo& setPClearValues( const ClearValue* pClearValues_ )
+    {
+      pClearValues = pClearValues_;
+      return *this;
+    }
+
+    operator const VkRenderPassBeginInfo&() const
+    {
+      return *reinterpret_cast<const VkRenderPassBeginInfo*>(this);
+    }
+
+    bool operator==( RenderPassBeginInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( renderPass == rhs.renderPass )
+          && ( framebuffer == rhs.framebuffer )
+          && ( renderArea == rhs.renderArea )
+          && ( clearValueCount == rhs.clearValueCount )
+          && ( pClearValues == rhs.pClearValues );
+    }
+
+    bool operator!=( RenderPassBeginInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    RenderPass renderPass;
+    Framebuffer framebuffer;
+    Rect2D renderArea;
+    uint32_t clearValueCount;
+    const ClearValue* pClearValues;
+  };
+  static_assert( sizeof( RenderPassBeginInfo ) == sizeof( VkRenderPassBeginInfo ), "struct and wrapper have different size!" );
+
+  struct EventCreateInfo
+  {
+    EventCreateInfo( EventCreateFlags flags_ = EventCreateFlags() )
+      : sType( StructureType::eEventCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+    {
+    }
+
+    EventCreateInfo( VkEventCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(EventCreateInfo) );
+    }
+
+    EventCreateInfo& operator=( VkEventCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(EventCreateInfo) );
+      return *this;
+    }
+
+    EventCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    EventCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    EventCreateInfo& setFlags( EventCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    operator const VkEventCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkEventCreateInfo*>(this);
+    }
+
+    bool operator==( EventCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags );
+    }
+
+    bool operator!=( EventCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    EventCreateFlags flags;
+  };
+  static_assert( sizeof( EventCreateInfo ) == sizeof( VkEventCreateInfo ), "struct and wrapper have different size!" );
+
+  struct SemaphoreCreateInfo
+  {
+    SemaphoreCreateInfo( SemaphoreCreateFlags flags_ = SemaphoreCreateFlags() )
+      : sType( StructureType::eSemaphoreCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+    {
+    }
+
+    SemaphoreCreateInfo( VkSemaphoreCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SemaphoreCreateInfo) );
+    }
+
+    SemaphoreCreateInfo& operator=( VkSemaphoreCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SemaphoreCreateInfo) );
+      return *this;
+    }
+
+    SemaphoreCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    SemaphoreCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    SemaphoreCreateInfo& setFlags( SemaphoreCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    operator const VkSemaphoreCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkSemaphoreCreateInfo*>(this);
+    }
+
+    bool operator==( SemaphoreCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags );
+    }
+
+    bool operator!=( SemaphoreCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    SemaphoreCreateFlags flags;
+  };
+  static_assert( sizeof( SemaphoreCreateInfo ) == sizeof( VkSemaphoreCreateInfo ), "struct and wrapper have different size!" );
+
+  struct FramebufferCreateInfo
+  {
+    FramebufferCreateInfo( FramebufferCreateFlags flags_ = FramebufferCreateFlags(), RenderPass renderPass_ = RenderPass(), uint32_t attachmentCount_ = 0, const ImageView* pAttachments_ = nullptr, uint32_t width_ = 0, uint32_t height_ = 0, uint32_t layers_ = 0 )
+      : sType( StructureType::eFramebufferCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , renderPass( renderPass_ )
+      , attachmentCount( attachmentCount_ )
+      , pAttachments( pAttachments_ )
+      , width( width_ )
+      , height( height_ )
+      , layers( layers_ )
+    {
+    }
+
+    FramebufferCreateInfo( VkFramebufferCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(FramebufferCreateInfo) );
+    }
+
+    FramebufferCreateInfo& operator=( VkFramebufferCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(FramebufferCreateInfo) );
+      return *this;
+    }
+
+    FramebufferCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    FramebufferCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    FramebufferCreateInfo& setFlags( FramebufferCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    FramebufferCreateInfo& setRenderPass( RenderPass renderPass_ )
+    {
+      renderPass = renderPass_;
+      return *this;
+    }
+
+    FramebufferCreateInfo& setAttachmentCount( uint32_t attachmentCount_ )
+    {
+      attachmentCount = attachmentCount_;
+      return *this;
+    }
+
+    FramebufferCreateInfo& setPAttachments( const ImageView* pAttachments_ )
+    {
+      pAttachments = pAttachments_;
+      return *this;
+    }
+
+    FramebufferCreateInfo& setWidth( uint32_t width_ )
+    {
+      width = width_;
+      return *this;
+    }
+
+    FramebufferCreateInfo& setHeight( uint32_t height_ )
+    {
+      height = height_;
+      return *this;
+    }
+
+    FramebufferCreateInfo& setLayers( uint32_t layers_ )
+    {
+      layers = layers_;
+      return *this;
+    }
+
+    operator const VkFramebufferCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkFramebufferCreateInfo*>(this);
+    }
+
+    bool operator==( FramebufferCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( renderPass == rhs.renderPass )
+          && ( attachmentCount == rhs.attachmentCount )
+          && ( pAttachments == rhs.pAttachments )
+          && ( width == rhs.width )
+          && ( height == rhs.height )
+          && ( layers == rhs.layers );
+    }
+
+    bool operator!=( FramebufferCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    FramebufferCreateFlags flags;
+    RenderPass renderPass;
+    uint32_t attachmentCount;
+    const ImageView* pAttachments;
+    uint32_t width;
+    uint32_t height;
+    uint32_t layers;
+  };
+  static_assert( sizeof( FramebufferCreateInfo ) == sizeof( VkFramebufferCreateInfo ), "struct and wrapper have different size!" );
+
+  struct DisplayModeCreateInfoKHR
+  {
+    DisplayModeCreateInfoKHR( DisplayModeCreateFlagsKHR flags_ = DisplayModeCreateFlagsKHR(), DisplayModeParametersKHR parameters_ = DisplayModeParametersKHR() )
+      : sType( StructureType::eDisplayModeCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , parameters( parameters_ )
+    {
+    }
+
+    DisplayModeCreateInfoKHR( VkDisplayModeCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayModeCreateInfoKHR) );
+    }
+
+    DisplayModeCreateInfoKHR& operator=( VkDisplayModeCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayModeCreateInfoKHR) );
+      return *this;
+    }
+
+    DisplayModeCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DisplayModeCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DisplayModeCreateInfoKHR& setFlags( DisplayModeCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    DisplayModeCreateInfoKHR& setParameters( DisplayModeParametersKHR parameters_ )
+    {
+      parameters = parameters_;
+      return *this;
+    }
+
+    operator const VkDisplayModeCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkDisplayModeCreateInfoKHR*>(this);
+    }
+
+    bool operator==( DisplayModeCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( parameters == rhs.parameters );
+    }
+
+    bool operator!=( DisplayModeCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DisplayModeCreateFlagsKHR flags;
+    DisplayModeParametersKHR parameters;
+  };
+  static_assert( sizeof( DisplayModeCreateInfoKHR ) == sizeof( VkDisplayModeCreateInfoKHR ), "struct and wrapper have different size!" );
+
+  struct DisplayPresentInfoKHR
+  {
+    DisplayPresentInfoKHR( Rect2D srcRect_ = Rect2D(), Rect2D dstRect_ = Rect2D(), Bool32 persistent_ = 0 )
+      : sType( StructureType::eDisplayPresentInfoKHR )
+      , pNext( nullptr )
+      , srcRect( srcRect_ )
+      , dstRect( dstRect_ )
+      , persistent( persistent_ )
+    {
+    }
+
+    DisplayPresentInfoKHR( VkDisplayPresentInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayPresentInfoKHR) );
+    }
+
+    DisplayPresentInfoKHR& operator=( VkDisplayPresentInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayPresentInfoKHR) );
+      return *this;
+    }
+
+    DisplayPresentInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DisplayPresentInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DisplayPresentInfoKHR& setSrcRect( Rect2D srcRect_ )
+    {
+      srcRect = srcRect_;
+      return *this;
+    }
+
+    DisplayPresentInfoKHR& setDstRect( Rect2D dstRect_ )
+    {
+      dstRect = dstRect_;
+      return *this;
+    }
+
+    DisplayPresentInfoKHR& setPersistent( Bool32 persistent_ )
+    {
+      persistent = persistent_;
+      return *this;
+    }
+
+    operator const VkDisplayPresentInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkDisplayPresentInfoKHR*>(this);
+    }
+
+    bool operator==( DisplayPresentInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( srcRect == rhs.srcRect )
+          && ( dstRect == rhs.dstRect )
+          && ( persistent == rhs.persistent );
+    }
+
+    bool operator!=( DisplayPresentInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    Rect2D srcRect;
+    Rect2D dstRect;
+    Bool32 persistent;
+  };
+  static_assert( sizeof( DisplayPresentInfoKHR ) == sizeof( VkDisplayPresentInfoKHR ), "struct and wrapper have different size!" );
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+  struct AndroidSurfaceCreateInfoKHR
+  {
+    AndroidSurfaceCreateInfoKHR( AndroidSurfaceCreateFlagsKHR flags_ = AndroidSurfaceCreateFlagsKHR(), ANativeWindow* window_ = nullptr )
+      : sType( StructureType::eAndroidSurfaceCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , window( window_ )
+    {
+    }
+
+    AndroidSurfaceCreateInfoKHR( VkAndroidSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(AndroidSurfaceCreateInfoKHR) );
+    }
+
+    AndroidSurfaceCreateInfoKHR& operator=( VkAndroidSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(AndroidSurfaceCreateInfoKHR) );
+      return *this;
+    }
+
+    AndroidSurfaceCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    AndroidSurfaceCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    AndroidSurfaceCreateInfoKHR& setFlags( AndroidSurfaceCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    AndroidSurfaceCreateInfoKHR& setWindow( ANativeWindow* window_ )
+    {
+      window = window_;
+      return *this;
+    }
+
+    operator const VkAndroidSurfaceCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkAndroidSurfaceCreateInfoKHR*>(this);
+    }
+
+    bool operator==( AndroidSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( window == rhs.window );
+    }
+
+    bool operator!=( AndroidSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    AndroidSurfaceCreateFlagsKHR flags;
+    ANativeWindow* window;
+  };
+  static_assert( sizeof( AndroidSurfaceCreateInfoKHR ) == sizeof( VkAndroidSurfaceCreateInfoKHR ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+  struct MirSurfaceCreateInfoKHR
+  {
+    MirSurfaceCreateInfoKHR( MirSurfaceCreateFlagsKHR flags_ = MirSurfaceCreateFlagsKHR(), MirConnection* connection_ = nullptr, MirSurface* mirSurface_ = nullptr )
+      : sType( StructureType::eMirSurfaceCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , connection( connection_ )
+      , mirSurface( mirSurface_ )
+    {
+    }
+
+    MirSurfaceCreateInfoKHR( VkMirSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(MirSurfaceCreateInfoKHR) );
+    }
+
+    MirSurfaceCreateInfoKHR& operator=( VkMirSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(MirSurfaceCreateInfoKHR) );
+      return *this;
+    }
+
+    MirSurfaceCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    MirSurfaceCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    MirSurfaceCreateInfoKHR& setFlags( MirSurfaceCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    MirSurfaceCreateInfoKHR& setConnection( MirConnection* connection_ )
+    {
+      connection = connection_;
+      return *this;
+    }
+
+    MirSurfaceCreateInfoKHR& setMirSurface( MirSurface* mirSurface_ )
+    {
+      mirSurface = mirSurface_;
+      return *this;
+    }
+
+    operator const VkMirSurfaceCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkMirSurfaceCreateInfoKHR*>(this);
+    }
+
+    bool operator==( MirSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( connection == rhs.connection )
+          && ( mirSurface == rhs.mirSurface );
+    }
+
+    bool operator!=( MirSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    MirSurfaceCreateFlagsKHR flags;
+    MirConnection* connection;
+    MirSurface* mirSurface;
+  };
+  static_assert( sizeof( MirSurfaceCreateInfoKHR ) == sizeof( VkMirSurfaceCreateInfoKHR ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+  struct WaylandSurfaceCreateInfoKHR
+  {
+    WaylandSurfaceCreateInfoKHR( WaylandSurfaceCreateFlagsKHR flags_ = WaylandSurfaceCreateFlagsKHR(), struct wl_display* display_ = nullptr, struct wl_surface* surface_ = nullptr )
+      : sType( StructureType::eWaylandSurfaceCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , display( display_ )
+      , surface( surface_ )
+    {
+    }
+
+    WaylandSurfaceCreateInfoKHR( VkWaylandSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(WaylandSurfaceCreateInfoKHR) );
+    }
+
+    WaylandSurfaceCreateInfoKHR& operator=( VkWaylandSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(WaylandSurfaceCreateInfoKHR) );
+      return *this;
+    }
+
+    WaylandSurfaceCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    WaylandSurfaceCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    WaylandSurfaceCreateInfoKHR& setFlags( WaylandSurfaceCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    WaylandSurfaceCreateInfoKHR& setDisplay( struct wl_display* display_ )
+    {
+      display = display_;
+      return *this;
+    }
+
+    WaylandSurfaceCreateInfoKHR& setSurface( struct wl_surface* surface_ )
+    {
+      surface = surface_;
+      return *this;
+    }
+
+    operator const VkWaylandSurfaceCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkWaylandSurfaceCreateInfoKHR*>(this);
+    }
+
+    bool operator==( WaylandSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( display == rhs.display )
+          && ( surface == rhs.surface );
+    }
+
+    bool operator!=( WaylandSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    WaylandSurfaceCreateFlagsKHR flags;
+    struct wl_display* display;
+    struct wl_surface* surface;
+  };
+  static_assert( sizeof( WaylandSurfaceCreateInfoKHR ) == sizeof( VkWaylandSurfaceCreateInfoKHR ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+  struct Win32SurfaceCreateInfoKHR
+  {
+    Win32SurfaceCreateInfoKHR( Win32SurfaceCreateFlagsKHR flags_ = Win32SurfaceCreateFlagsKHR(), HINSTANCE hinstance_ = 0, HWND hwnd_ = 0 )
+      : sType( StructureType::eWin32SurfaceCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , hinstance( hinstance_ )
+      , hwnd( hwnd_ )
+    {
+    }
+
+    Win32SurfaceCreateInfoKHR( VkWin32SurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Win32SurfaceCreateInfoKHR) );
+    }
+
+    Win32SurfaceCreateInfoKHR& operator=( VkWin32SurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Win32SurfaceCreateInfoKHR) );
+      return *this;
+    }
+
+    Win32SurfaceCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    Win32SurfaceCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    Win32SurfaceCreateInfoKHR& setFlags( Win32SurfaceCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    Win32SurfaceCreateInfoKHR& setHinstance( HINSTANCE hinstance_ )
+    {
+      hinstance = hinstance_;
+      return *this;
+    }
+
+    Win32SurfaceCreateInfoKHR& setHwnd( HWND hwnd_ )
+    {
+      hwnd = hwnd_;
+      return *this;
+    }
+
+    operator const VkWin32SurfaceCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkWin32SurfaceCreateInfoKHR*>(this);
+    }
+
+    bool operator==( Win32SurfaceCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( hinstance == rhs.hinstance )
+          && ( hwnd == rhs.hwnd );
+    }
+
+    bool operator!=( Win32SurfaceCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    Win32SurfaceCreateFlagsKHR flags;
+    HINSTANCE hinstance;
+    HWND hwnd;
+  };
+  static_assert( sizeof( Win32SurfaceCreateInfoKHR ) == sizeof( VkWin32SurfaceCreateInfoKHR ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+  struct XlibSurfaceCreateInfoKHR
+  {
+    XlibSurfaceCreateInfoKHR( XlibSurfaceCreateFlagsKHR flags_ = XlibSurfaceCreateFlagsKHR(), Display* dpy_ = nullptr, Window window_ = 0 )
+      : sType( StructureType::eXlibSurfaceCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , dpy( dpy_ )
+      , window( window_ )
+    {
+    }
+
+    XlibSurfaceCreateInfoKHR( VkXlibSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(XlibSurfaceCreateInfoKHR) );
+    }
+
+    XlibSurfaceCreateInfoKHR& operator=( VkXlibSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(XlibSurfaceCreateInfoKHR) );
+      return *this;
+    }
+
+    XlibSurfaceCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    XlibSurfaceCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    XlibSurfaceCreateInfoKHR& setFlags( XlibSurfaceCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    XlibSurfaceCreateInfoKHR& setDpy( Display* dpy_ )
+    {
+      dpy = dpy_;
+      return *this;
+    }
+
+    XlibSurfaceCreateInfoKHR& setWindow( Window window_ )
+    {
+      window = window_;
+      return *this;
+    }
+
+    operator const VkXlibSurfaceCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkXlibSurfaceCreateInfoKHR*>(this);
+    }
+
+    bool operator==( XlibSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( dpy == rhs.dpy )
+          && ( window == rhs.window );
+    }
+
+    bool operator!=( XlibSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    XlibSurfaceCreateFlagsKHR flags;
+    Display* dpy;
+    Window window;
+  };
+  static_assert( sizeof( XlibSurfaceCreateInfoKHR ) == sizeof( VkXlibSurfaceCreateInfoKHR ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+  struct XcbSurfaceCreateInfoKHR
+  {
+    XcbSurfaceCreateInfoKHR( XcbSurfaceCreateFlagsKHR flags_ = XcbSurfaceCreateFlagsKHR(), xcb_connection_t* connection_ = nullptr, xcb_window_t window_ = 0 )
+      : sType( StructureType::eXcbSurfaceCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , connection( connection_ )
+      , window( window_ )
+    {
+    }
+
+    XcbSurfaceCreateInfoKHR( VkXcbSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(XcbSurfaceCreateInfoKHR) );
+    }
+
+    XcbSurfaceCreateInfoKHR& operator=( VkXcbSurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(XcbSurfaceCreateInfoKHR) );
+      return *this;
+    }
+
+    XcbSurfaceCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    XcbSurfaceCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    XcbSurfaceCreateInfoKHR& setFlags( XcbSurfaceCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    XcbSurfaceCreateInfoKHR& setConnection( xcb_connection_t* connection_ )
+    {
+      connection = connection_;
+      return *this;
+    }
+
+    XcbSurfaceCreateInfoKHR& setWindow( xcb_window_t window_ )
+    {
+      window = window_;
+      return *this;
+    }
+
+    operator const VkXcbSurfaceCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkXcbSurfaceCreateInfoKHR*>(this);
+    }
+
+    bool operator==( XcbSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( connection == rhs.connection )
+          && ( window == rhs.window );
+    }
+
+    bool operator!=( XcbSurfaceCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    XcbSurfaceCreateFlagsKHR flags;
+    xcb_connection_t* connection;
+    xcb_window_t window;
+  };
+  static_assert( sizeof( XcbSurfaceCreateInfoKHR ) == sizeof( VkXcbSurfaceCreateInfoKHR ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+  struct DebugMarkerMarkerInfoEXT
+  {
+    DebugMarkerMarkerInfoEXT( const char* pMarkerName_ = nullptr, std::array<float,4> const& color_ = { { 0, 0, 0, 0 } } )
+      : sType( StructureType::eDebugMarkerMarkerInfoEXT )
+      , pNext( nullptr )
+      , pMarkerName( pMarkerName_ )
+    {
+      memcpy( &color, color_.data(), 4 * sizeof( float ) );
+    }
+
+    DebugMarkerMarkerInfoEXT( VkDebugMarkerMarkerInfoEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DebugMarkerMarkerInfoEXT) );
+    }
+
+    DebugMarkerMarkerInfoEXT& operator=( VkDebugMarkerMarkerInfoEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DebugMarkerMarkerInfoEXT) );
+      return *this;
+    }
+
+    DebugMarkerMarkerInfoEXT& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DebugMarkerMarkerInfoEXT& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DebugMarkerMarkerInfoEXT& setPMarkerName( const char* pMarkerName_ )
+    {
+      pMarkerName = pMarkerName_;
+      return *this;
+    }
+
+    DebugMarkerMarkerInfoEXT& setColor( std::array<float,4> color_ )
+    {
+      memcpy( &color, color_.data(), 4 * sizeof( float ) );
+      return *this;
+    }
+
+    operator const VkDebugMarkerMarkerInfoEXT&() const
+    {
+      return *reinterpret_cast<const VkDebugMarkerMarkerInfoEXT*>(this);
+    }
+
+    bool operator==( DebugMarkerMarkerInfoEXT const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( pMarkerName == rhs.pMarkerName )
+          && ( memcmp( color, rhs.color, 4 * sizeof( float ) ) == 0 );
+    }
+
+    bool operator!=( DebugMarkerMarkerInfoEXT const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    const char* pMarkerName;
+    float color[4];
+  };
+  static_assert( sizeof( DebugMarkerMarkerInfoEXT ) == sizeof( VkDebugMarkerMarkerInfoEXT ), "struct and wrapper have different size!" );
+
+  struct DedicatedAllocationImageCreateInfoNV
+  {
+    DedicatedAllocationImageCreateInfoNV( Bool32 dedicatedAllocation_ = 0 )
+      : sType( StructureType::eDedicatedAllocationImageCreateInfoNV )
+      , pNext( nullptr )
+      , dedicatedAllocation( dedicatedAllocation_ )
+    {
+    }
+
+    DedicatedAllocationImageCreateInfoNV( VkDedicatedAllocationImageCreateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DedicatedAllocationImageCreateInfoNV) );
+    }
+
+    DedicatedAllocationImageCreateInfoNV& operator=( VkDedicatedAllocationImageCreateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DedicatedAllocationImageCreateInfoNV) );
+      return *this;
+    }
+
+    DedicatedAllocationImageCreateInfoNV& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DedicatedAllocationImageCreateInfoNV& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DedicatedAllocationImageCreateInfoNV& setDedicatedAllocation( Bool32 dedicatedAllocation_ )
+    {
+      dedicatedAllocation = dedicatedAllocation_;
+      return *this;
+    }
+
+    operator const VkDedicatedAllocationImageCreateInfoNV&() const
+    {
+      return *reinterpret_cast<const VkDedicatedAllocationImageCreateInfoNV*>(this);
+    }
+
+    bool operator==( DedicatedAllocationImageCreateInfoNV const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( dedicatedAllocation == rhs.dedicatedAllocation );
+    }
+
+    bool operator!=( DedicatedAllocationImageCreateInfoNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    Bool32 dedicatedAllocation;
+  };
+  static_assert( sizeof( DedicatedAllocationImageCreateInfoNV ) == sizeof( VkDedicatedAllocationImageCreateInfoNV ), "struct and wrapper have different size!" );
+
+  struct DedicatedAllocationBufferCreateInfoNV
+  {
+    DedicatedAllocationBufferCreateInfoNV( Bool32 dedicatedAllocation_ = 0 )
+      : sType( StructureType::eDedicatedAllocationBufferCreateInfoNV )
+      , pNext( nullptr )
+      , dedicatedAllocation( dedicatedAllocation_ )
+    {
+    }
+
+    DedicatedAllocationBufferCreateInfoNV( VkDedicatedAllocationBufferCreateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DedicatedAllocationBufferCreateInfoNV) );
+    }
+
+    DedicatedAllocationBufferCreateInfoNV& operator=( VkDedicatedAllocationBufferCreateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DedicatedAllocationBufferCreateInfoNV) );
+      return *this;
+    }
+
+    DedicatedAllocationBufferCreateInfoNV& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DedicatedAllocationBufferCreateInfoNV& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DedicatedAllocationBufferCreateInfoNV& setDedicatedAllocation( Bool32 dedicatedAllocation_ )
+    {
+      dedicatedAllocation = dedicatedAllocation_;
+      return *this;
+    }
+
+    operator const VkDedicatedAllocationBufferCreateInfoNV&() const
+    {
+      return *reinterpret_cast<const VkDedicatedAllocationBufferCreateInfoNV*>(this);
+    }
+
+    bool operator==( DedicatedAllocationBufferCreateInfoNV const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( dedicatedAllocation == rhs.dedicatedAllocation );
+    }
+
+    bool operator!=( DedicatedAllocationBufferCreateInfoNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    Bool32 dedicatedAllocation;
+  };
+  static_assert( sizeof( DedicatedAllocationBufferCreateInfoNV ) == sizeof( VkDedicatedAllocationBufferCreateInfoNV ), "struct and wrapper have different size!" );
+
+  struct DedicatedAllocationMemoryAllocateInfoNV
+  {
+    DedicatedAllocationMemoryAllocateInfoNV( Image image_ = Image(), Buffer buffer_ = Buffer() )
+      : sType( StructureType::eDedicatedAllocationMemoryAllocateInfoNV )
+      , pNext( nullptr )
+      , image( image_ )
+      , buffer( buffer_ )
+    {
+    }
+
+    DedicatedAllocationMemoryAllocateInfoNV( VkDedicatedAllocationMemoryAllocateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DedicatedAllocationMemoryAllocateInfoNV) );
+    }
+
+    DedicatedAllocationMemoryAllocateInfoNV& operator=( VkDedicatedAllocationMemoryAllocateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DedicatedAllocationMemoryAllocateInfoNV) );
+      return *this;
+    }
+
+    DedicatedAllocationMemoryAllocateInfoNV& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DedicatedAllocationMemoryAllocateInfoNV& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DedicatedAllocationMemoryAllocateInfoNV& setImage( Image image_ )
+    {
+      image = image_;
+      return *this;
+    }
+
+    DedicatedAllocationMemoryAllocateInfoNV& setBuffer( Buffer buffer_ )
+    {
+      buffer = buffer_;
+      return *this;
+    }
+
+    operator const VkDedicatedAllocationMemoryAllocateInfoNV&() const
+    {
+      return *reinterpret_cast<const VkDedicatedAllocationMemoryAllocateInfoNV*>(this);
+    }
+
+    bool operator==( DedicatedAllocationMemoryAllocateInfoNV const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( image == rhs.image )
+          && ( buffer == rhs.buffer );
+    }
+
+    bool operator!=( DedicatedAllocationMemoryAllocateInfoNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    Image image;
+    Buffer buffer;
+  };
+  static_assert( sizeof( DedicatedAllocationMemoryAllocateInfoNV ) == sizeof( VkDedicatedAllocationMemoryAllocateInfoNV ), "struct and wrapper have different size!" );
+
+  enum class SubpassContents
+  {
+    eInline = VK_SUBPASS_CONTENTS_INLINE,
+    eSecondaryCommandBuffers = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS
+  };
+
+  struct PresentInfoKHR
+  {
+    PresentInfoKHR( uint32_t waitSemaphoreCount_ = 0, const Semaphore* pWaitSemaphores_ = nullptr, uint32_t swapchainCount_ = 0, const SwapchainKHR* pSwapchains_ = nullptr, const uint32_t* pImageIndices_ = nullptr, Result* pResults_ = nullptr )
+      : sType( StructureType::ePresentInfoKHR )
+      , pNext( nullptr )
+      , waitSemaphoreCount( waitSemaphoreCount_ )
+      , pWaitSemaphores( pWaitSemaphores_ )
+      , swapchainCount( swapchainCount_ )
+      , pSwapchains( pSwapchains_ )
+      , pImageIndices( pImageIndices_ )
+      , pResults( pResults_ )
+    {
+    }
+
+    PresentInfoKHR( VkPresentInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PresentInfoKHR) );
+    }
+
+    PresentInfoKHR& operator=( VkPresentInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PresentInfoKHR) );
+      return *this;
+    }
+
+    PresentInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PresentInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PresentInfoKHR& setWaitSemaphoreCount( uint32_t waitSemaphoreCount_ )
+    {
+      waitSemaphoreCount = waitSemaphoreCount_;
+      return *this;
+    }
+
+    PresentInfoKHR& setPWaitSemaphores( const Semaphore* pWaitSemaphores_ )
+    {
+      pWaitSemaphores = pWaitSemaphores_;
+      return *this;
+    }
+
+    PresentInfoKHR& setSwapchainCount( uint32_t swapchainCount_ )
+    {
+      swapchainCount = swapchainCount_;
+      return *this;
+    }
+
+    PresentInfoKHR& setPSwapchains( const SwapchainKHR* pSwapchains_ )
+    {
+      pSwapchains = pSwapchains_;
+      return *this;
+    }
+
+    PresentInfoKHR& setPImageIndices( const uint32_t* pImageIndices_ )
+    {
+      pImageIndices = pImageIndices_;
+      return *this;
+    }
+
+    PresentInfoKHR& setPResults( Result* pResults_ )
+    {
+      pResults = pResults_;
+      return *this;
+    }
+
+    operator const VkPresentInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkPresentInfoKHR*>(this);
+    }
+
+    bool operator==( PresentInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( waitSemaphoreCount == rhs.waitSemaphoreCount )
+          && ( pWaitSemaphores == rhs.pWaitSemaphores )
+          && ( swapchainCount == rhs.swapchainCount )
+          && ( pSwapchains == rhs.pSwapchains )
+          && ( pImageIndices == rhs.pImageIndices )
+          && ( pResults == rhs.pResults );
+    }
+
+    bool operator!=( PresentInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    uint32_t waitSemaphoreCount;
+    const Semaphore* pWaitSemaphores;
+    uint32_t swapchainCount;
+    const SwapchainKHR* pSwapchains;
+    const uint32_t* pImageIndices;
+    Result* pResults;
+  };
+  static_assert( sizeof( PresentInfoKHR ) == sizeof( VkPresentInfoKHR ), "struct and wrapper have different size!" );
+
+  enum class DynamicState
+  {
+    eViewport = VK_DYNAMIC_STATE_VIEWPORT,
+    eScissor = VK_DYNAMIC_STATE_SCISSOR,
+    eLineWidth = VK_DYNAMIC_STATE_LINE_WIDTH,
+    eDepthBias = VK_DYNAMIC_STATE_DEPTH_BIAS,
+    eBlendConstants = VK_DYNAMIC_STATE_BLEND_CONSTANTS,
+    eDepthBounds = VK_DYNAMIC_STATE_DEPTH_BOUNDS,
+    eStencilCompareMask = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
+    eStencilWriteMask = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
+    eStencilReference = VK_DYNAMIC_STATE_STENCIL_REFERENCE
+  };
+
+  struct PipelineDynamicStateCreateInfo
+  {
+    PipelineDynamicStateCreateInfo( PipelineDynamicStateCreateFlags flags_ = PipelineDynamicStateCreateFlags(), uint32_t dynamicStateCount_ = 0, const DynamicState* pDynamicStates_ = nullptr )
+      : sType( StructureType::ePipelineDynamicStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , dynamicStateCount( dynamicStateCount_ )
+      , pDynamicStates( pDynamicStates_ )
+    {
+    }
+
+    PipelineDynamicStateCreateInfo( VkPipelineDynamicStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineDynamicStateCreateInfo) );
+    }
+
+    PipelineDynamicStateCreateInfo& operator=( VkPipelineDynamicStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineDynamicStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineDynamicStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineDynamicStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineDynamicStateCreateInfo& setFlags( PipelineDynamicStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineDynamicStateCreateInfo& setDynamicStateCount( uint32_t dynamicStateCount_ )
+    {
+      dynamicStateCount = dynamicStateCount_;
+      return *this;
+    }
+
+    PipelineDynamicStateCreateInfo& setPDynamicStates( const DynamicState* pDynamicStates_ )
+    {
+      pDynamicStates = pDynamicStates_;
+      return *this;
+    }
+
+    operator const VkPipelineDynamicStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineDynamicStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineDynamicStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( dynamicStateCount == rhs.dynamicStateCount )
+          && ( pDynamicStates == rhs.pDynamicStates );
+    }
+
+    bool operator!=( PipelineDynamicStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineDynamicStateCreateFlags flags;
+    uint32_t dynamicStateCount;
+    const DynamicState* pDynamicStates;
+  };
+  static_assert( sizeof( PipelineDynamicStateCreateInfo ) == sizeof( VkPipelineDynamicStateCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class QueueFlagBits
+  {
+    eGraphics = VK_QUEUE_GRAPHICS_BIT,
+    eCompute = VK_QUEUE_COMPUTE_BIT,
+    eTransfer = VK_QUEUE_TRANSFER_BIT,
+    eSparseBinding = VK_QUEUE_SPARSE_BINDING_BIT
+  };
+
+  using QueueFlags = Flags<QueueFlagBits, VkQueueFlags>;
+
+  inline QueueFlags operator|( QueueFlagBits bit0, QueueFlagBits bit1 )
+  {
+    return QueueFlags( bit0 ) | bit1;
+  }
+
+  struct QueueFamilyProperties
+  {
+    operator const VkQueueFamilyProperties&() const
+    {
+      return *reinterpret_cast<const VkQueueFamilyProperties*>(this);
+    }
+
+    bool operator==( QueueFamilyProperties const& rhs ) const
+    {
+      return ( queueFlags == rhs.queueFlags )
+          && ( queueCount == rhs.queueCount )
+          && ( timestampValidBits == rhs.timestampValidBits )
+          && ( minImageTransferGranularity == rhs.minImageTransferGranularity );
+    }
+
+    bool operator!=( QueueFamilyProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    QueueFlags queueFlags;
+    uint32_t queueCount;
+    uint32_t timestampValidBits;
+    Extent3D minImageTransferGranularity;
+  };
+  static_assert( sizeof( QueueFamilyProperties ) == sizeof( VkQueueFamilyProperties ), "struct and wrapper have different size!" );
+
+  enum class MemoryPropertyFlagBits
+  {
+    eDeviceLocal = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+    eHostVisible = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+    eHostCoherent = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+    eHostCached = VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+    eLazilyAllocated = VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
+  };
+
+  using MemoryPropertyFlags = Flags<MemoryPropertyFlagBits, VkMemoryPropertyFlags>;
+
+  inline MemoryPropertyFlags operator|( MemoryPropertyFlagBits bit0, MemoryPropertyFlagBits bit1 )
+  {
+    return MemoryPropertyFlags( bit0 ) | bit1;
+  }
+
+  struct MemoryType
+  {
+    operator const VkMemoryType&() const
+    {
+      return *reinterpret_cast<const VkMemoryType*>(this);
+    }
+
+    bool operator==( MemoryType const& rhs ) const
+    {
+      return ( propertyFlags == rhs.propertyFlags )
+          && ( heapIndex == rhs.heapIndex );
+    }
+
+    bool operator!=( MemoryType const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    MemoryPropertyFlags propertyFlags;
+    uint32_t heapIndex;
+  };
+  static_assert( sizeof( MemoryType ) == sizeof( VkMemoryType ), "struct and wrapper have different size!" );
+
+  enum class MemoryHeapFlagBits
+  {
+    eDeviceLocal = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
+  };
+
+  using MemoryHeapFlags = Flags<MemoryHeapFlagBits, VkMemoryHeapFlags>;
+
+  inline MemoryHeapFlags operator|( MemoryHeapFlagBits bit0, MemoryHeapFlagBits bit1 )
+  {
+    return MemoryHeapFlags( bit0 ) | bit1;
+  }
+
+  struct MemoryHeap
+  {
+    operator const VkMemoryHeap&() const
+    {
+      return *reinterpret_cast<const VkMemoryHeap*>(this);
+    }
+
+    bool operator==( MemoryHeap const& rhs ) const
+    {
+      return ( size == rhs.size )
+          && ( flags == rhs.flags );
+    }
+
+    bool operator!=( MemoryHeap const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DeviceSize size;
+    MemoryHeapFlags flags;
+  };
+  static_assert( sizeof( MemoryHeap ) == sizeof( VkMemoryHeap ), "struct and wrapper have different size!" );
+
+  struct PhysicalDeviceMemoryProperties
+  {
+    operator const VkPhysicalDeviceMemoryProperties&() const
+    {
+      return *reinterpret_cast<const VkPhysicalDeviceMemoryProperties*>(this);
+    }
+
+    bool operator==( PhysicalDeviceMemoryProperties const& rhs ) const
+    {
+      return ( memoryTypeCount == rhs.memoryTypeCount )
+          && ( memcmp( memoryTypes, rhs.memoryTypes, VK_MAX_MEMORY_TYPES * sizeof( MemoryType ) ) == 0 )
+          && ( memoryHeapCount == rhs.memoryHeapCount )
+          && ( memcmp( memoryHeaps, rhs.memoryHeaps, VK_MAX_MEMORY_HEAPS * sizeof( MemoryHeap ) ) == 0 );
+    }
+
+    bool operator!=( PhysicalDeviceMemoryProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t memoryTypeCount;
+    MemoryType memoryTypes[VK_MAX_MEMORY_TYPES];
+    uint32_t memoryHeapCount;
+    MemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS];
+  };
+  static_assert( sizeof( PhysicalDeviceMemoryProperties ) == sizeof( VkPhysicalDeviceMemoryProperties ), "struct and wrapper have different size!" );
+
+  enum class AccessFlagBits
+  {
+    eIndirectCommandRead = VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
+    eIndexRead = VK_ACCESS_INDEX_READ_BIT,
+    eVertexAttributeRead = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
+    eUniformRead = VK_ACCESS_UNIFORM_READ_BIT,
+    eInputAttachmentRead = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
+    eShaderRead = VK_ACCESS_SHADER_READ_BIT,
+    eShaderWrite = VK_ACCESS_SHADER_WRITE_BIT,
+    eColorAttachmentRead = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
+    eColorAttachmentWrite = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+    eDepthStencilAttachmentRead = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
+    eDepthStencilAttachmentWrite = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
+    eTransferRead = VK_ACCESS_TRANSFER_READ_BIT,
+    eTransferWrite = VK_ACCESS_TRANSFER_WRITE_BIT,
+    eHostRead = VK_ACCESS_HOST_READ_BIT,
+    eHostWrite = VK_ACCESS_HOST_WRITE_BIT,
+    eMemoryRead = VK_ACCESS_MEMORY_READ_BIT,
+    eMemoryWrite = VK_ACCESS_MEMORY_WRITE_BIT
+  };
+
+  using AccessFlags = Flags<AccessFlagBits, VkAccessFlags>;
+
+  inline AccessFlags operator|( AccessFlagBits bit0, AccessFlagBits bit1 )
+  {
+    return AccessFlags( bit0 ) | bit1;
+  }
+
+  struct MemoryBarrier
+  {
+    MemoryBarrier( AccessFlags srcAccessMask_ = AccessFlags(), AccessFlags dstAccessMask_ = AccessFlags() )
+      : sType( StructureType::eMemoryBarrier )
+      , pNext( nullptr )
+      , srcAccessMask( srcAccessMask_ )
+      , dstAccessMask( dstAccessMask_ )
+    {
+    }
+
+    MemoryBarrier( VkMemoryBarrier const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(MemoryBarrier) );
+    }
+
+    MemoryBarrier& operator=( VkMemoryBarrier const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(MemoryBarrier) );
+      return *this;
+    }
+
+    MemoryBarrier& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    MemoryBarrier& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    MemoryBarrier& setSrcAccessMask( AccessFlags srcAccessMask_ )
+    {
+      srcAccessMask = srcAccessMask_;
+      return *this;
+    }
+
+    MemoryBarrier& setDstAccessMask( AccessFlags dstAccessMask_ )
+    {
+      dstAccessMask = dstAccessMask_;
+      return *this;
+    }
+
+    operator const VkMemoryBarrier&() const
+    {
+      return *reinterpret_cast<const VkMemoryBarrier*>(this);
+    }
+
+    bool operator==( MemoryBarrier const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( srcAccessMask == rhs.srcAccessMask )
+          && ( dstAccessMask == rhs.dstAccessMask );
+    }
+
+    bool operator!=( MemoryBarrier const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    AccessFlags srcAccessMask;
+    AccessFlags dstAccessMask;
+  };
+  static_assert( sizeof( MemoryBarrier ) == sizeof( VkMemoryBarrier ), "struct and wrapper have different size!" );
+
+  struct BufferMemoryBarrier
+  {
+    BufferMemoryBarrier( AccessFlags srcAccessMask_ = AccessFlags(), AccessFlags dstAccessMask_ = AccessFlags(), uint32_t srcQueueFamilyIndex_ = 0, uint32_t dstQueueFamilyIndex_ = 0, Buffer buffer_ = Buffer(), DeviceSize offset_ = 0, DeviceSize size_ = 0 )
+      : sType( StructureType::eBufferMemoryBarrier )
+      , pNext( nullptr )
+      , srcAccessMask( srcAccessMask_ )
+      , dstAccessMask( dstAccessMask_ )
+      , srcQueueFamilyIndex( srcQueueFamilyIndex_ )
+      , dstQueueFamilyIndex( dstQueueFamilyIndex_ )
+      , buffer( buffer_ )
+      , offset( offset_ )
+      , size( size_ )
+    {
+    }
+
+    BufferMemoryBarrier( VkBufferMemoryBarrier const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferMemoryBarrier) );
+    }
+
+    BufferMemoryBarrier& operator=( VkBufferMemoryBarrier const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferMemoryBarrier) );
+      return *this;
+    }
+
+    BufferMemoryBarrier& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    BufferMemoryBarrier& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    BufferMemoryBarrier& setSrcAccessMask( AccessFlags srcAccessMask_ )
+    {
+      srcAccessMask = srcAccessMask_;
+      return *this;
+    }
+
+    BufferMemoryBarrier& setDstAccessMask( AccessFlags dstAccessMask_ )
+    {
+      dstAccessMask = dstAccessMask_;
+      return *this;
+    }
+
+    BufferMemoryBarrier& setSrcQueueFamilyIndex( uint32_t srcQueueFamilyIndex_ )
+    {
+      srcQueueFamilyIndex = srcQueueFamilyIndex_;
+      return *this;
+    }
+
+    BufferMemoryBarrier& setDstQueueFamilyIndex( uint32_t dstQueueFamilyIndex_ )
+    {
+      dstQueueFamilyIndex = dstQueueFamilyIndex_;
+      return *this;
+    }
+
+    BufferMemoryBarrier& setBuffer( Buffer buffer_ )
+    {
+      buffer = buffer_;
+      return *this;
+    }
+
+    BufferMemoryBarrier& setOffset( DeviceSize offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    BufferMemoryBarrier& setSize( DeviceSize size_ )
+    {
+      size = size_;
+      return *this;
+    }
+
+    operator const VkBufferMemoryBarrier&() const
+    {
+      return *reinterpret_cast<const VkBufferMemoryBarrier*>(this);
+    }
+
+    bool operator==( BufferMemoryBarrier const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( srcAccessMask == rhs.srcAccessMask )
+          && ( dstAccessMask == rhs.dstAccessMask )
+          && ( srcQueueFamilyIndex == rhs.srcQueueFamilyIndex )
+          && ( dstQueueFamilyIndex == rhs.dstQueueFamilyIndex )
+          && ( buffer == rhs.buffer )
+          && ( offset == rhs.offset )
+          && ( size == rhs.size );
+    }
+
+    bool operator!=( BufferMemoryBarrier const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    AccessFlags srcAccessMask;
+    AccessFlags dstAccessMask;
+    uint32_t srcQueueFamilyIndex;
+    uint32_t dstQueueFamilyIndex;
+    Buffer buffer;
+    DeviceSize offset;
+    DeviceSize size;
+  };
+  static_assert( sizeof( BufferMemoryBarrier ) == sizeof( VkBufferMemoryBarrier ), "struct and wrapper have different size!" );
+
+  enum class BufferUsageFlagBits
+  {
+    eTransferSrc = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+    eTransferDst = VK_BUFFER_USAGE_TRANSFER_DST_BIT,
+    eUniformTexelBuffer = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
+    eStorageTexelBuffer = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
+    eUniformBuffer = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+    eStorageBuffer = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+    eIndexBuffer = VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
+    eVertexBuffer = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
+    eIndirectBuffer = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
+  };
+
+  using BufferUsageFlags = Flags<BufferUsageFlagBits, VkBufferUsageFlags>;
+
+  inline BufferUsageFlags operator|( BufferUsageFlagBits bit0, BufferUsageFlagBits bit1 )
+  {
+    return BufferUsageFlags( bit0 ) | bit1;
+  }
+
+  enum class BufferCreateFlagBits
+  {
+    eSparseBinding = VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
+    eSparseResidency = VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
+    eSparseAliased = VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
+  };
+
+  using BufferCreateFlags = Flags<BufferCreateFlagBits, VkBufferCreateFlags>;
+
+  inline BufferCreateFlags operator|( BufferCreateFlagBits bit0, BufferCreateFlagBits bit1 )
+  {
+    return BufferCreateFlags( bit0 ) | bit1;
+  }
+
+  struct BufferCreateInfo
+  {
+    BufferCreateInfo( BufferCreateFlags flags_ = BufferCreateFlags(), DeviceSize size_ = 0, BufferUsageFlags usage_ = BufferUsageFlags(), SharingMode sharingMode_ = SharingMode::eExclusive, uint32_t queueFamilyIndexCount_ = 0, const uint32_t* pQueueFamilyIndices_ = nullptr )
+      : sType( StructureType::eBufferCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , size( size_ )
+      , usage( usage_ )
+      , sharingMode( sharingMode_ )
+      , queueFamilyIndexCount( queueFamilyIndexCount_ )
+      , pQueueFamilyIndices( pQueueFamilyIndices_ )
+    {
+    }
+
+    BufferCreateInfo( VkBufferCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferCreateInfo) );
+    }
+
+    BufferCreateInfo& operator=( VkBufferCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferCreateInfo) );
+      return *this;
+    }
+
+    BufferCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    BufferCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    BufferCreateInfo& setFlags( BufferCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    BufferCreateInfo& setSize( DeviceSize size_ )
+    {
+      size = size_;
+      return *this;
+    }
+
+    BufferCreateInfo& setUsage( BufferUsageFlags usage_ )
+    {
+      usage = usage_;
+      return *this;
+    }
+
+    BufferCreateInfo& setSharingMode( SharingMode sharingMode_ )
+    {
+      sharingMode = sharingMode_;
+      return *this;
+    }
+
+    BufferCreateInfo& setQueueFamilyIndexCount( uint32_t queueFamilyIndexCount_ )
+    {
+      queueFamilyIndexCount = queueFamilyIndexCount_;
+      return *this;
+    }
+
+    BufferCreateInfo& setPQueueFamilyIndices( const uint32_t* pQueueFamilyIndices_ )
+    {
+      pQueueFamilyIndices = pQueueFamilyIndices_;
+      return *this;
+    }
+
+    operator const VkBufferCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkBufferCreateInfo*>(this);
+    }
+
+    bool operator==( BufferCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( size == rhs.size )
+          && ( usage == rhs.usage )
+          && ( sharingMode == rhs.sharingMode )
+          && ( queueFamilyIndexCount == rhs.queueFamilyIndexCount )
+          && ( pQueueFamilyIndices == rhs.pQueueFamilyIndices );
+    }
+
+    bool operator!=( BufferCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    BufferCreateFlags flags;
+    DeviceSize size;
+    BufferUsageFlags usage;
+    SharingMode sharingMode;
+    uint32_t queueFamilyIndexCount;
+    const uint32_t* pQueueFamilyIndices;
+  };
+  static_assert( sizeof( BufferCreateInfo ) == sizeof( VkBufferCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class ShaderStageFlagBits
+  {
+    eVertex = VK_SHADER_STAGE_VERTEX_BIT,
+    eTessellationControl = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
+    eTessellationEvaluation = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
+    eGeometry = VK_SHADER_STAGE_GEOMETRY_BIT,
+    eFragment = VK_SHADER_STAGE_FRAGMENT_BIT,
+    eCompute = VK_SHADER_STAGE_COMPUTE_BIT,
+    eAllGraphics = VK_SHADER_STAGE_ALL_GRAPHICS,
+    eAll = VK_SHADER_STAGE_ALL
+  };
+
+  using ShaderStageFlags = Flags<ShaderStageFlagBits, VkShaderStageFlags>;
+
+  inline ShaderStageFlags operator|( ShaderStageFlagBits bit0, ShaderStageFlagBits bit1 )
+  {
+    return ShaderStageFlags( bit0 ) | bit1;
+  }
+
+  struct DescriptorSetLayoutBinding
+  {
+    DescriptorSetLayoutBinding( uint32_t binding_ = 0, DescriptorType descriptorType_ = DescriptorType::eSampler, uint32_t descriptorCount_ = 0, ShaderStageFlags stageFlags_ = ShaderStageFlags(), const Sampler* pImmutableSamplers_ = nullptr )
+      : binding( binding_ )
+      , descriptorType( descriptorType_ )
+      , descriptorCount( descriptorCount_ )
+      , stageFlags( stageFlags_ )
+      , pImmutableSamplers( pImmutableSamplers_ )
+    {
+    }
+
+    DescriptorSetLayoutBinding( VkDescriptorSetLayoutBinding const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorSetLayoutBinding) );
+    }
+
+    DescriptorSetLayoutBinding& operator=( VkDescriptorSetLayoutBinding const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorSetLayoutBinding) );
+      return *this;
+    }
+
+    DescriptorSetLayoutBinding& setBinding( uint32_t binding_ )
+    {
+      binding = binding_;
+      return *this;
+    }
+
+    DescriptorSetLayoutBinding& setDescriptorType( DescriptorType descriptorType_ )
+    {
+      descriptorType = descriptorType_;
+      return *this;
+    }
+
+    DescriptorSetLayoutBinding& setDescriptorCount( uint32_t descriptorCount_ )
+    {
+      descriptorCount = descriptorCount_;
+      return *this;
+    }
+
+    DescriptorSetLayoutBinding& setStageFlags( ShaderStageFlags stageFlags_ )
+    {
+      stageFlags = stageFlags_;
+      return *this;
+    }
+
+    DescriptorSetLayoutBinding& setPImmutableSamplers( const Sampler* pImmutableSamplers_ )
+    {
+      pImmutableSamplers = pImmutableSamplers_;
+      return *this;
+    }
+
+    operator const VkDescriptorSetLayoutBinding&() const
+    {
+      return *reinterpret_cast<const VkDescriptorSetLayoutBinding*>(this);
+    }
+
+    bool operator==( DescriptorSetLayoutBinding const& rhs ) const
+    {
+      return ( binding == rhs.binding )
+          && ( descriptorType == rhs.descriptorType )
+          && ( descriptorCount == rhs.descriptorCount )
+          && ( stageFlags == rhs.stageFlags )
+          && ( pImmutableSamplers == rhs.pImmutableSamplers );
+    }
+
+    bool operator!=( DescriptorSetLayoutBinding const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t binding;
+    DescriptorType descriptorType;
+    uint32_t descriptorCount;
+    ShaderStageFlags stageFlags;
+    const Sampler* pImmutableSamplers;
+  };
+  static_assert( sizeof( DescriptorSetLayoutBinding ) == sizeof( VkDescriptorSetLayoutBinding ), "struct and wrapper have different size!" );
+
+  struct DescriptorSetLayoutCreateInfo
+  {
+    DescriptorSetLayoutCreateInfo( DescriptorSetLayoutCreateFlags flags_ = DescriptorSetLayoutCreateFlags(), uint32_t bindingCount_ = 0, const DescriptorSetLayoutBinding* pBindings_ = nullptr )
+      : sType( StructureType::eDescriptorSetLayoutCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , bindingCount( bindingCount_ )
+      , pBindings( pBindings_ )
+    {
+    }
+
+    DescriptorSetLayoutCreateInfo( VkDescriptorSetLayoutCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorSetLayoutCreateInfo) );
+    }
+
+    DescriptorSetLayoutCreateInfo& operator=( VkDescriptorSetLayoutCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorSetLayoutCreateInfo) );
+      return *this;
+    }
+
+    DescriptorSetLayoutCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DescriptorSetLayoutCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DescriptorSetLayoutCreateInfo& setFlags( DescriptorSetLayoutCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    DescriptorSetLayoutCreateInfo& setBindingCount( uint32_t bindingCount_ )
+    {
+      bindingCount = bindingCount_;
+      return *this;
+    }
+
+    DescriptorSetLayoutCreateInfo& setPBindings( const DescriptorSetLayoutBinding* pBindings_ )
+    {
+      pBindings = pBindings_;
+      return *this;
+    }
+
+    operator const VkDescriptorSetLayoutCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkDescriptorSetLayoutCreateInfo*>(this);
+    }
+
+    bool operator==( DescriptorSetLayoutCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( bindingCount == rhs.bindingCount )
+          && ( pBindings == rhs.pBindings );
+    }
+
+    bool operator!=( DescriptorSetLayoutCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DescriptorSetLayoutCreateFlags flags;
+    uint32_t bindingCount;
+    const DescriptorSetLayoutBinding* pBindings;
+  };
+  static_assert( sizeof( DescriptorSetLayoutCreateInfo ) == sizeof( VkDescriptorSetLayoutCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineShaderStageCreateInfo
+  {
+    PipelineShaderStageCreateInfo( PipelineShaderStageCreateFlags flags_ = PipelineShaderStageCreateFlags(), ShaderStageFlagBits stage_ = ShaderStageFlagBits::eVertex, ShaderModule module_ = ShaderModule(), const char* pName_ = nullptr, const SpecializationInfo* pSpecializationInfo_ = nullptr )
+      : sType( StructureType::ePipelineShaderStageCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , stage( stage_ )
+      , module( module_ )
+      , pName( pName_ )
+      , pSpecializationInfo( pSpecializationInfo_ )
+    {
+    }
+
+    PipelineShaderStageCreateInfo( VkPipelineShaderStageCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineShaderStageCreateInfo) );
+    }
+
+    PipelineShaderStageCreateInfo& operator=( VkPipelineShaderStageCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineShaderStageCreateInfo) );
+      return *this;
+    }
+
+    PipelineShaderStageCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineShaderStageCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineShaderStageCreateInfo& setFlags( PipelineShaderStageCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineShaderStageCreateInfo& setStage( ShaderStageFlagBits stage_ )
+    {
+      stage = stage_;
+      return *this;
+    }
+
+    PipelineShaderStageCreateInfo& setModule( ShaderModule module_ )
+    {
+      module = module_;
+      return *this;
+    }
+
+    PipelineShaderStageCreateInfo& setPName( const char* pName_ )
+    {
+      pName = pName_;
+      return *this;
+    }
+
+    PipelineShaderStageCreateInfo& setPSpecializationInfo( const SpecializationInfo* pSpecializationInfo_ )
+    {
+      pSpecializationInfo = pSpecializationInfo_;
+      return *this;
+    }
+
+    operator const VkPipelineShaderStageCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineShaderStageCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineShaderStageCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( stage == rhs.stage )
+          && ( module == rhs.module )
+          && ( pName == rhs.pName )
+          && ( pSpecializationInfo == rhs.pSpecializationInfo );
+    }
+
+    bool operator!=( PipelineShaderStageCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineShaderStageCreateFlags flags;
+    ShaderStageFlagBits stage;
+    ShaderModule module;
+    const char* pName;
+    const SpecializationInfo* pSpecializationInfo;
+  };
+  static_assert( sizeof( PipelineShaderStageCreateInfo ) == sizeof( VkPipelineShaderStageCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PushConstantRange
+  {
+    PushConstantRange( ShaderStageFlags stageFlags_ = ShaderStageFlags(), uint32_t offset_ = 0, uint32_t size_ = 0 )
+      : stageFlags( stageFlags_ )
+      , offset( offset_ )
+      , size( size_ )
+    {
+    }
+
+    PushConstantRange( VkPushConstantRange const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PushConstantRange) );
+    }
+
+    PushConstantRange& operator=( VkPushConstantRange const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PushConstantRange) );
+      return *this;
+    }
+
+    PushConstantRange& setStageFlags( ShaderStageFlags stageFlags_ )
+    {
+      stageFlags = stageFlags_;
+      return *this;
+    }
+
+    PushConstantRange& setOffset( uint32_t offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    PushConstantRange& setSize( uint32_t size_ )
+    {
+      size = size_;
+      return *this;
+    }
+
+    operator const VkPushConstantRange&() const
+    {
+      return *reinterpret_cast<const VkPushConstantRange*>(this);
+    }
+
+    bool operator==( PushConstantRange const& rhs ) const
+    {
+      return ( stageFlags == rhs.stageFlags )
+          && ( offset == rhs.offset )
+          && ( size == rhs.size );
+    }
+
+    bool operator!=( PushConstantRange const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ShaderStageFlags stageFlags;
+    uint32_t offset;
+    uint32_t size;
+  };
+  static_assert( sizeof( PushConstantRange ) == sizeof( VkPushConstantRange ), "struct and wrapper have different size!" );
+
+  struct PipelineLayoutCreateInfo
+  {
+    PipelineLayoutCreateInfo( PipelineLayoutCreateFlags flags_ = PipelineLayoutCreateFlags(), uint32_t setLayoutCount_ = 0, const DescriptorSetLayout* pSetLayouts_ = nullptr, uint32_t pushConstantRangeCount_ = 0, const PushConstantRange* pPushConstantRanges_ = nullptr )
+      : sType( StructureType::ePipelineLayoutCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , setLayoutCount( setLayoutCount_ )
+      , pSetLayouts( pSetLayouts_ )
+      , pushConstantRangeCount( pushConstantRangeCount_ )
+      , pPushConstantRanges( pPushConstantRanges_ )
+    {
+    }
+
+    PipelineLayoutCreateInfo( VkPipelineLayoutCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineLayoutCreateInfo) );
+    }
+
+    PipelineLayoutCreateInfo& operator=( VkPipelineLayoutCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineLayoutCreateInfo) );
+      return *this;
+    }
+
+    PipelineLayoutCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineLayoutCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineLayoutCreateInfo& setFlags( PipelineLayoutCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineLayoutCreateInfo& setSetLayoutCount( uint32_t setLayoutCount_ )
+    {
+      setLayoutCount = setLayoutCount_;
+      return *this;
+    }
+
+    PipelineLayoutCreateInfo& setPSetLayouts( const DescriptorSetLayout* pSetLayouts_ )
+    {
+      pSetLayouts = pSetLayouts_;
+      return *this;
+    }
+
+    PipelineLayoutCreateInfo& setPushConstantRangeCount( uint32_t pushConstantRangeCount_ )
+    {
+      pushConstantRangeCount = pushConstantRangeCount_;
+      return *this;
+    }
+
+    PipelineLayoutCreateInfo& setPPushConstantRanges( const PushConstantRange* pPushConstantRanges_ )
+    {
+      pPushConstantRanges = pPushConstantRanges_;
+      return *this;
+    }
+
+    operator const VkPipelineLayoutCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineLayoutCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineLayoutCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( setLayoutCount == rhs.setLayoutCount )
+          && ( pSetLayouts == rhs.pSetLayouts )
+          && ( pushConstantRangeCount == rhs.pushConstantRangeCount )
+          && ( pPushConstantRanges == rhs.pPushConstantRanges );
+    }
+
+    bool operator!=( PipelineLayoutCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineLayoutCreateFlags flags;
+    uint32_t setLayoutCount;
+    const DescriptorSetLayout* pSetLayouts;
+    uint32_t pushConstantRangeCount;
+    const PushConstantRange* pPushConstantRanges;
+  };
+  static_assert( sizeof( PipelineLayoutCreateInfo ) == sizeof( VkPipelineLayoutCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class ImageUsageFlagBits
+  {
+    eTransferSrc = VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+    eTransferDst = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+    eSampled = VK_IMAGE_USAGE_SAMPLED_BIT,
+    eStorage = VK_IMAGE_USAGE_STORAGE_BIT,
+    eColorAttachment = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+    eDepthStencilAttachment = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+    eTransientAttachment = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
+    eInputAttachment = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
+  };
+
+  using ImageUsageFlags = Flags<ImageUsageFlagBits, VkImageUsageFlags>;
+
+  inline ImageUsageFlags operator|( ImageUsageFlagBits bit0, ImageUsageFlagBits bit1 )
+  {
+    return ImageUsageFlags( bit0 ) | bit1;
+  }
+
+  enum class ImageCreateFlagBits
+  {
+    eSparseBinding = VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
+    eSparseResidency = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
+    eSparseAliased = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
+    eMutableFormat = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
+    eCubeCompatible = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
+  };
+
+  using ImageCreateFlags = Flags<ImageCreateFlagBits, VkImageCreateFlags>;
+
+  inline ImageCreateFlags operator|( ImageCreateFlagBits bit0, ImageCreateFlagBits bit1 )
+  {
+    return ImageCreateFlags( bit0 ) | bit1;
+  }
+
+  enum class PipelineCreateFlagBits
+  {
+    eDisableOptimization = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
+    eAllowDerivatives = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT,
+    eDerivative = VK_PIPELINE_CREATE_DERIVATIVE_BIT
+  };
+
+  using PipelineCreateFlags = Flags<PipelineCreateFlagBits, VkPipelineCreateFlags>;
+
+  inline PipelineCreateFlags operator|( PipelineCreateFlagBits bit0, PipelineCreateFlagBits bit1 )
+  {
+    return PipelineCreateFlags( bit0 ) | bit1;
+  }
+
+  struct ComputePipelineCreateInfo
+  {
+    ComputePipelineCreateInfo( PipelineCreateFlags flags_ = PipelineCreateFlags(), PipelineShaderStageCreateInfo stage_ = PipelineShaderStageCreateInfo(), PipelineLayout layout_ = PipelineLayout(), Pipeline basePipelineHandle_ = Pipeline(), int32_t basePipelineIndex_ = 0 )
+      : sType( StructureType::eComputePipelineCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , stage( stage_ )
+      , layout( layout_ )
+      , basePipelineHandle( basePipelineHandle_ )
+      , basePipelineIndex( basePipelineIndex_ )
+    {
+    }
+
+    ComputePipelineCreateInfo( VkComputePipelineCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ComputePipelineCreateInfo) );
+    }
+
+    ComputePipelineCreateInfo& operator=( VkComputePipelineCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ComputePipelineCreateInfo) );
+      return *this;
+    }
+
+    ComputePipelineCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ComputePipelineCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ComputePipelineCreateInfo& setFlags( PipelineCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    ComputePipelineCreateInfo& setStage( PipelineShaderStageCreateInfo stage_ )
+    {
+      stage = stage_;
+      return *this;
+    }
+
+    ComputePipelineCreateInfo& setLayout( PipelineLayout layout_ )
+    {
+      layout = layout_;
+      return *this;
+    }
+
+    ComputePipelineCreateInfo& setBasePipelineHandle( Pipeline basePipelineHandle_ )
+    {
+      basePipelineHandle = basePipelineHandle_;
+      return *this;
+    }
+
+    ComputePipelineCreateInfo& setBasePipelineIndex( int32_t basePipelineIndex_ )
+    {
+      basePipelineIndex = basePipelineIndex_;
+      return *this;
+    }
+
+    operator const VkComputePipelineCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkComputePipelineCreateInfo*>(this);
+    }
+
+    bool operator==( ComputePipelineCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( stage == rhs.stage )
+          && ( layout == rhs.layout )
+          && ( basePipelineHandle == rhs.basePipelineHandle )
+          && ( basePipelineIndex == rhs.basePipelineIndex );
+    }
+
+    bool operator!=( ComputePipelineCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineCreateFlags flags;
+    PipelineShaderStageCreateInfo stage;
+    PipelineLayout layout;
+    Pipeline basePipelineHandle;
+    int32_t basePipelineIndex;
+  };
+  static_assert( sizeof( ComputePipelineCreateInfo ) == sizeof( VkComputePipelineCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class ColorComponentFlagBits
+  {
+    eR = VK_COLOR_COMPONENT_R_BIT,
+    eG = VK_COLOR_COMPONENT_G_BIT,
+    eB = VK_COLOR_COMPONENT_B_BIT,
+    eA = VK_COLOR_COMPONENT_A_BIT
+  };
+
+  using ColorComponentFlags = Flags<ColorComponentFlagBits, VkColorComponentFlags>;
+
+  inline ColorComponentFlags operator|( ColorComponentFlagBits bit0, ColorComponentFlagBits bit1 )
+  {
+    return ColorComponentFlags( bit0 ) | bit1;
+  }
+
+  struct PipelineColorBlendAttachmentState
+  {
+    PipelineColorBlendAttachmentState( Bool32 blendEnable_ = 0, BlendFactor srcColorBlendFactor_ = BlendFactor::eZero, BlendFactor dstColorBlendFactor_ = BlendFactor::eZero, BlendOp colorBlendOp_ = BlendOp::eAdd, BlendFactor srcAlphaBlendFactor_ = BlendFactor::eZero, BlendFactor dstAlphaBlendFactor_ = BlendFactor::eZero, BlendOp alphaBlendOp_ = BlendOp::eAdd, ColorComponentFlags colorWriteMask_ = ColorComponentFlags() )
+      : blendEnable( blendEnable_ )
+      , srcColorBlendFactor( srcColorBlendFactor_ )
+      , dstColorBlendFactor( dstColorBlendFactor_ )
+      , colorBlendOp( colorBlendOp_ )
+      , srcAlphaBlendFactor( srcAlphaBlendFactor_ )
+      , dstAlphaBlendFactor( dstAlphaBlendFactor_ )
+      , alphaBlendOp( alphaBlendOp_ )
+      , colorWriteMask( colorWriteMask_ )
+    {
+    }
+
+    PipelineColorBlendAttachmentState( VkPipelineColorBlendAttachmentState const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineColorBlendAttachmentState) );
+    }
+
+    PipelineColorBlendAttachmentState& operator=( VkPipelineColorBlendAttachmentState const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineColorBlendAttachmentState) );
+      return *this;
+    }
+
+    PipelineColorBlendAttachmentState& setBlendEnable( Bool32 blendEnable_ )
+    {
+      blendEnable = blendEnable_;
+      return *this;
+    }
+
+    PipelineColorBlendAttachmentState& setSrcColorBlendFactor( BlendFactor srcColorBlendFactor_ )
+    {
+      srcColorBlendFactor = srcColorBlendFactor_;
+      return *this;
+    }
+
+    PipelineColorBlendAttachmentState& setDstColorBlendFactor( BlendFactor dstColorBlendFactor_ )
+    {
+      dstColorBlendFactor = dstColorBlendFactor_;
+      return *this;
+    }
+
+    PipelineColorBlendAttachmentState& setColorBlendOp( BlendOp colorBlendOp_ )
+    {
+      colorBlendOp = colorBlendOp_;
+      return *this;
+    }
+
+    PipelineColorBlendAttachmentState& setSrcAlphaBlendFactor( BlendFactor srcAlphaBlendFactor_ )
+    {
+      srcAlphaBlendFactor = srcAlphaBlendFactor_;
+      return *this;
+    }
+
+    PipelineColorBlendAttachmentState& setDstAlphaBlendFactor( BlendFactor dstAlphaBlendFactor_ )
+    {
+      dstAlphaBlendFactor = dstAlphaBlendFactor_;
+      return *this;
+    }
+
+    PipelineColorBlendAttachmentState& setAlphaBlendOp( BlendOp alphaBlendOp_ )
+    {
+      alphaBlendOp = alphaBlendOp_;
+      return *this;
+    }
+
+    PipelineColorBlendAttachmentState& setColorWriteMask( ColorComponentFlags colorWriteMask_ )
+    {
+      colorWriteMask = colorWriteMask_;
+      return *this;
+    }
+
+    operator const VkPipelineColorBlendAttachmentState&() const
+    {
+      return *reinterpret_cast<const VkPipelineColorBlendAttachmentState*>(this);
+    }
+
+    bool operator==( PipelineColorBlendAttachmentState const& rhs ) const
+    {
+      return ( blendEnable == rhs.blendEnable )
+          && ( srcColorBlendFactor == rhs.srcColorBlendFactor )
+          && ( dstColorBlendFactor == rhs.dstColorBlendFactor )
+          && ( colorBlendOp == rhs.colorBlendOp )
+          && ( srcAlphaBlendFactor == rhs.srcAlphaBlendFactor )
+          && ( dstAlphaBlendFactor == rhs.dstAlphaBlendFactor )
+          && ( alphaBlendOp == rhs.alphaBlendOp )
+          && ( colorWriteMask == rhs.colorWriteMask );
+    }
+
+    bool operator!=( PipelineColorBlendAttachmentState const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Bool32 blendEnable;
+    BlendFactor srcColorBlendFactor;
+    BlendFactor dstColorBlendFactor;
+    BlendOp colorBlendOp;
+    BlendFactor srcAlphaBlendFactor;
+    BlendFactor dstAlphaBlendFactor;
+    BlendOp alphaBlendOp;
+    ColorComponentFlags colorWriteMask;
+  };
+  static_assert( sizeof( PipelineColorBlendAttachmentState ) == sizeof( VkPipelineColorBlendAttachmentState ), "struct and wrapper have different size!" );
+
+  struct PipelineColorBlendStateCreateInfo
+  {
+    PipelineColorBlendStateCreateInfo( PipelineColorBlendStateCreateFlags flags_ = PipelineColorBlendStateCreateFlags(), Bool32 logicOpEnable_ = 0, LogicOp logicOp_ = LogicOp::eClear, uint32_t attachmentCount_ = 0, const PipelineColorBlendAttachmentState* pAttachments_ = nullptr, std::array<float,4> const& blendConstants_ = { { 0, 0, 0, 0 } } )
+      : sType( StructureType::ePipelineColorBlendStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , logicOpEnable( logicOpEnable_ )
+      , logicOp( logicOp_ )
+      , attachmentCount( attachmentCount_ )
+      , pAttachments( pAttachments_ )
+    {
+      memcpy( &blendConstants, blendConstants_.data(), 4 * sizeof( float ) );
+    }
+
+    PipelineColorBlendStateCreateInfo( VkPipelineColorBlendStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineColorBlendStateCreateInfo) );
+    }
+
+    PipelineColorBlendStateCreateInfo& operator=( VkPipelineColorBlendStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineColorBlendStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineColorBlendStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineColorBlendStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineColorBlendStateCreateInfo& setFlags( PipelineColorBlendStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineColorBlendStateCreateInfo& setLogicOpEnable( Bool32 logicOpEnable_ )
+    {
+      logicOpEnable = logicOpEnable_;
+      return *this;
+    }
+
+    PipelineColorBlendStateCreateInfo& setLogicOp( LogicOp logicOp_ )
+    {
+      logicOp = logicOp_;
+      return *this;
+    }
+
+    PipelineColorBlendStateCreateInfo& setAttachmentCount( uint32_t attachmentCount_ )
+    {
+      attachmentCount = attachmentCount_;
+      return *this;
+    }
+
+    PipelineColorBlendStateCreateInfo& setPAttachments( const PipelineColorBlendAttachmentState* pAttachments_ )
+    {
+      pAttachments = pAttachments_;
+      return *this;
+    }
+
+    PipelineColorBlendStateCreateInfo& setBlendConstants( std::array<float,4> blendConstants_ )
+    {
+      memcpy( &blendConstants, blendConstants_.data(), 4 * sizeof( float ) );
+      return *this;
+    }
+
+    operator const VkPipelineColorBlendStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineColorBlendStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineColorBlendStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( logicOpEnable == rhs.logicOpEnable )
+          && ( logicOp == rhs.logicOp )
+          && ( attachmentCount == rhs.attachmentCount )
+          && ( pAttachments == rhs.pAttachments )
+          && ( memcmp( blendConstants, rhs.blendConstants, 4 * sizeof( float ) ) == 0 );
+    }
+
+    bool operator!=( PipelineColorBlendStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineColorBlendStateCreateFlags flags;
+    Bool32 logicOpEnable;
+    LogicOp logicOp;
+    uint32_t attachmentCount;
+    const PipelineColorBlendAttachmentState* pAttachments;
+    float blendConstants[4];
+  };
+  static_assert( sizeof( PipelineColorBlendStateCreateInfo ) == sizeof( VkPipelineColorBlendStateCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class FenceCreateFlagBits
+  {
+    eSignaled = VK_FENCE_CREATE_SIGNALED_BIT
+  };
+
+  using FenceCreateFlags = Flags<FenceCreateFlagBits, VkFenceCreateFlags>;
+
+  inline FenceCreateFlags operator|( FenceCreateFlagBits bit0, FenceCreateFlagBits bit1 )
+  {
+    return FenceCreateFlags( bit0 ) | bit1;
+  }
+
+  struct FenceCreateInfo
+  {
+    FenceCreateInfo( FenceCreateFlags flags_ = FenceCreateFlags() )
+      : sType( StructureType::eFenceCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+    {
+    }
+
+    FenceCreateInfo( VkFenceCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(FenceCreateInfo) );
+    }
+
+    FenceCreateInfo& operator=( VkFenceCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(FenceCreateInfo) );
+      return *this;
+    }
+
+    FenceCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    FenceCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    FenceCreateInfo& setFlags( FenceCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    operator const VkFenceCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkFenceCreateInfo*>(this);
+    }
+
+    bool operator==( FenceCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags );
+    }
+
+    bool operator!=( FenceCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    FenceCreateFlags flags;
+  };
+  static_assert( sizeof( FenceCreateInfo ) == sizeof( VkFenceCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class FormatFeatureFlagBits
+  {
+    eSampledImage = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT,
+    eStorageImage = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT,
+    eStorageImageAtomic = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT,
+    eUniformTexelBuffer = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT,
+    eStorageTexelBuffer = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT,
+    eStorageTexelBufferAtomic = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT,
+    eVertexBuffer = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT,
+    eColorAttachment = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT,
+    eColorAttachmentBlend = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT,
+    eDepthStencilAttachment = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT,
+    eBlitSrc = VK_FORMAT_FEATURE_BLIT_SRC_BIT,
+    eBlitDst = VK_FORMAT_FEATURE_BLIT_DST_BIT,
+    eSampledImageFilterLinear = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT,
+    eSampledImageFilterCubicIMG = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG
+  };
+
+  using FormatFeatureFlags = Flags<FormatFeatureFlagBits, VkFormatFeatureFlags>;
+
+  inline FormatFeatureFlags operator|( FormatFeatureFlagBits bit0, FormatFeatureFlagBits bit1 )
+  {
+    return FormatFeatureFlags( bit0 ) | bit1;
+  }
+
+  struct FormatProperties
+  {
+    operator const VkFormatProperties&() const
+    {
+      return *reinterpret_cast<const VkFormatProperties*>(this);
+    }
+
+    bool operator==( FormatProperties const& rhs ) const
+    {
+      return ( linearTilingFeatures == rhs.linearTilingFeatures )
+          && ( optimalTilingFeatures == rhs.optimalTilingFeatures )
+          && ( bufferFeatures == rhs.bufferFeatures );
+    }
+
+    bool operator!=( FormatProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    FormatFeatureFlags linearTilingFeatures;
+    FormatFeatureFlags optimalTilingFeatures;
+    FormatFeatureFlags bufferFeatures;
+  };
+  static_assert( sizeof( FormatProperties ) == sizeof( VkFormatProperties ), "struct and wrapper have different size!" );
+
+  enum class QueryControlFlagBits
+  {
+    ePrecise = VK_QUERY_CONTROL_PRECISE_BIT
+  };
+
+  using QueryControlFlags = Flags<QueryControlFlagBits, VkQueryControlFlags>;
+
+  inline QueryControlFlags operator|( QueryControlFlagBits bit0, QueryControlFlagBits bit1 )
+  {
+    return QueryControlFlags( bit0 ) | bit1;
+  }
+
+  enum class QueryResultFlagBits
+  {
+    e64 = VK_QUERY_RESULT_64_BIT,
+    eWait = VK_QUERY_RESULT_WAIT_BIT,
+    eWithAvailability = VK_QUERY_RESULT_WITH_AVAILABILITY_BIT,
+    ePartial = VK_QUERY_RESULT_PARTIAL_BIT
+  };
+
+  using QueryResultFlags = Flags<QueryResultFlagBits, VkQueryResultFlags>;
+
+  inline QueryResultFlags operator|( QueryResultFlagBits bit0, QueryResultFlagBits bit1 )
+  {
+    return QueryResultFlags( bit0 ) | bit1;
+  }
+
+  enum class CommandBufferUsageFlagBits
+  {
+    eOneTimeSubmit = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
+    eRenderPassContinue = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
+    eSimultaneousUse = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
+  };
+
+  using CommandBufferUsageFlags = Flags<CommandBufferUsageFlagBits, VkCommandBufferUsageFlags>;
+
+  inline CommandBufferUsageFlags operator|( CommandBufferUsageFlagBits bit0, CommandBufferUsageFlagBits bit1 )
+  {
+    return CommandBufferUsageFlags( bit0 ) | bit1;
+  }
+
+  enum class QueryPipelineStatisticFlagBits
+  {
+    eInputAssemblyVertices = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT,
+    eInputAssemblyPrimitives = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT,
+    eVertexShaderInvocations = VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT,
+    eGeometryShaderInvocations = VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT,
+    eGeometryShaderPrimitives = VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT,
+    eClippingInvocations = VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT,
+    eClippingPrimitives = VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT,
+    eFragmentShaderInvocations = VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,
+    eTessellationControlShaderPatches = VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT,
+    eTessellationEvaluationShaderInvocations = VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT,
+    eComputeShaderInvocations = VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT
+  };
+
+  using QueryPipelineStatisticFlags = Flags<QueryPipelineStatisticFlagBits, VkQueryPipelineStatisticFlags>;
+
+  inline QueryPipelineStatisticFlags operator|( QueryPipelineStatisticFlagBits bit0, QueryPipelineStatisticFlagBits bit1 )
+  {
+    return QueryPipelineStatisticFlags( bit0 ) | bit1;
+  }
+
+  struct CommandBufferInheritanceInfo
+  {
+    CommandBufferInheritanceInfo( RenderPass renderPass_ = RenderPass(), uint32_t subpass_ = 0, Framebuffer framebuffer_ = Framebuffer(), Bool32 occlusionQueryEnable_ = 0, QueryControlFlags queryFlags_ = QueryControlFlags(), QueryPipelineStatisticFlags pipelineStatistics_ = QueryPipelineStatisticFlags() )
+      : sType( StructureType::eCommandBufferInheritanceInfo )
+      , pNext( nullptr )
+      , renderPass( renderPass_ )
+      , subpass( subpass_ )
+      , framebuffer( framebuffer_ )
+      , occlusionQueryEnable( occlusionQueryEnable_ )
+      , queryFlags( queryFlags_ )
+      , pipelineStatistics( pipelineStatistics_ )
+    {
+    }
+
+    CommandBufferInheritanceInfo( VkCommandBufferInheritanceInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CommandBufferInheritanceInfo) );
+    }
+
+    CommandBufferInheritanceInfo& operator=( VkCommandBufferInheritanceInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CommandBufferInheritanceInfo) );
+      return *this;
+    }
+
+    CommandBufferInheritanceInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    CommandBufferInheritanceInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    CommandBufferInheritanceInfo& setRenderPass( RenderPass renderPass_ )
+    {
+      renderPass = renderPass_;
+      return *this;
+    }
+
+    CommandBufferInheritanceInfo& setSubpass( uint32_t subpass_ )
+    {
+      subpass = subpass_;
+      return *this;
+    }
+
+    CommandBufferInheritanceInfo& setFramebuffer( Framebuffer framebuffer_ )
+    {
+      framebuffer = framebuffer_;
+      return *this;
+    }
+
+    CommandBufferInheritanceInfo& setOcclusionQueryEnable( Bool32 occlusionQueryEnable_ )
+    {
+      occlusionQueryEnable = occlusionQueryEnable_;
+      return *this;
+    }
+
+    CommandBufferInheritanceInfo& setQueryFlags( QueryControlFlags queryFlags_ )
+    {
+      queryFlags = queryFlags_;
+      return *this;
+    }
+
+    CommandBufferInheritanceInfo& setPipelineStatistics( QueryPipelineStatisticFlags pipelineStatistics_ )
+    {
+      pipelineStatistics = pipelineStatistics_;
+      return *this;
+    }
+
+    operator const VkCommandBufferInheritanceInfo&() const
+    {
+      return *reinterpret_cast<const VkCommandBufferInheritanceInfo*>(this);
+    }
+
+    bool operator==( CommandBufferInheritanceInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( renderPass == rhs.renderPass )
+          && ( subpass == rhs.subpass )
+          && ( framebuffer == rhs.framebuffer )
+          && ( occlusionQueryEnable == rhs.occlusionQueryEnable )
+          && ( queryFlags == rhs.queryFlags )
+          && ( pipelineStatistics == rhs.pipelineStatistics );
+    }
+
+    bool operator!=( CommandBufferInheritanceInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    RenderPass renderPass;
+    uint32_t subpass;
+    Framebuffer framebuffer;
+    Bool32 occlusionQueryEnable;
+    QueryControlFlags queryFlags;
+    QueryPipelineStatisticFlags pipelineStatistics;
+  };
+  static_assert( sizeof( CommandBufferInheritanceInfo ) == sizeof( VkCommandBufferInheritanceInfo ), "struct and wrapper have different size!" );
+
+  struct CommandBufferBeginInfo
+  {
+    CommandBufferBeginInfo( CommandBufferUsageFlags flags_ = CommandBufferUsageFlags(), const CommandBufferInheritanceInfo* pInheritanceInfo_ = nullptr )
+      : sType( StructureType::eCommandBufferBeginInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , pInheritanceInfo( pInheritanceInfo_ )
+    {
+    }
+
+    CommandBufferBeginInfo( VkCommandBufferBeginInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CommandBufferBeginInfo) );
+    }
+
+    CommandBufferBeginInfo& operator=( VkCommandBufferBeginInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CommandBufferBeginInfo) );
+      return *this;
+    }
+
+    CommandBufferBeginInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    CommandBufferBeginInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    CommandBufferBeginInfo& setFlags( CommandBufferUsageFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    CommandBufferBeginInfo& setPInheritanceInfo( const CommandBufferInheritanceInfo* pInheritanceInfo_ )
+    {
+      pInheritanceInfo = pInheritanceInfo_;
+      return *this;
+    }
+
+    operator const VkCommandBufferBeginInfo&() const
+    {
+      return *reinterpret_cast<const VkCommandBufferBeginInfo*>(this);
+    }
+
+    bool operator==( CommandBufferBeginInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( pInheritanceInfo == rhs.pInheritanceInfo );
+    }
+
+    bool operator!=( CommandBufferBeginInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    CommandBufferUsageFlags flags;
+    const CommandBufferInheritanceInfo* pInheritanceInfo;
+  };
+  static_assert( sizeof( CommandBufferBeginInfo ) == sizeof( VkCommandBufferBeginInfo ), "struct and wrapper have different size!" );
+
+  struct QueryPoolCreateInfo
+  {
+    QueryPoolCreateInfo( QueryPoolCreateFlags flags_ = QueryPoolCreateFlags(), QueryType queryType_ = QueryType::eOcclusion, uint32_t queryCount_ = 0, QueryPipelineStatisticFlags pipelineStatistics_ = QueryPipelineStatisticFlags() )
+      : sType( StructureType::eQueryPoolCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , queryType( queryType_ )
+      , queryCount( queryCount_ )
+      , pipelineStatistics( pipelineStatistics_ )
+    {
+    }
+
+    QueryPoolCreateInfo( VkQueryPoolCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(QueryPoolCreateInfo) );
+    }
+
+    QueryPoolCreateInfo& operator=( VkQueryPoolCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(QueryPoolCreateInfo) );
+      return *this;
+    }
+
+    QueryPoolCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    QueryPoolCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    QueryPoolCreateInfo& setFlags( QueryPoolCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    QueryPoolCreateInfo& setQueryType( QueryType queryType_ )
+    {
+      queryType = queryType_;
+      return *this;
+    }
+
+    QueryPoolCreateInfo& setQueryCount( uint32_t queryCount_ )
+    {
+      queryCount = queryCount_;
+      return *this;
+    }
+
+    QueryPoolCreateInfo& setPipelineStatistics( QueryPipelineStatisticFlags pipelineStatistics_ )
+    {
+      pipelineStatistics = pipelineStatistics_;
+      return *this;
+    }
+
+    operator const VkQueryPoolCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkQueryPoolCreateInfo*>(this);
+    }
+
+    bool operator==( QueryPoolCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( queryType == rhs.queryType )
+          && ( queryCount == rhs.queryCount )
+          && ( pipelineStatistics == rhs.pipelineStatistics );
+    }
+
+    bool operator!=( QueryPoolCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    QueryPoolCreateFlags flags;
+    QueryType queryType;
+    uint32_t queryCount;
+    QueryPipelineStatisticFlags pipelineStatistics;
+  };
+  static_assert( sizeof( QueryPoolCreateInfo ) == sizeof( VkQueryPoolCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class ImageAspectFlagBits
+  {
+    eColor = VK_IMAGE_ASPECT_COLOR_BIT,
+    eDepth = VK_IMAGE_ASPECT_DEPTH_BIT,
+    eStencil = VK_IMAGE_ASPECT_STENCIL_BIT,
+    eMetadata = VK_IMAGE_ASPECT_METADATA_BIT
+  };
+
+  using ImageAspectFlags = Flags<ImageAspectFlagBits, VkImageAspectFlags>;
+
+  inline ImageAspectFlags operator|( ImageAspectFlagBits bit0, ImageAspectFlagBits bit1 )
+  {
+    return ImageAspectFlags( bit0 ) | bit1;
+  }
+
+  struct ImageSubresource
+  {
+    ImageSubresource( ImageAspectFlags aspectMask_ = ImageAspectFlags(), uint32_t mipLevel_ = 0, uint32_t arrayLayer_ = 0 )
+      : aspectMask( aspectMask_ )
+      , mipLevel( mipLevel_ )
+      , arrayLayer( arrayLayer_ )
+    {
+    }
+
+    ImageSubresource( VkImageSubresource const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageSubresource) );
+    }
+
+    ImageSubresource& operator=( VkImageSubresource const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageSubresource) );
+      return *this;
+    }
+
+    ImageSubresource& setAspectMask( ImageAspectFlags aspectMask_ )
+    {
+      aspectMask = aspectMask_;
+      return *this;
+    }
+
+    ImageSubresource& setMipLevel( uint32_t mipLevel_ )
+    {
+      mipLevel = mipLevel_;
+      return *this;
+    }
+
+    ImageSubresource& setArrayLayer( uint32_t arrayLayer_ )
+    {
+      arrayLayer = arrayLayer_;
+      return *this;
+    }
+
+    operator const VkImageSubresource&() const
+    {
+      return *reinterpret_cast<const VkImageSubresource*>(this);
+    }
+
+    bool operator==( ImageSubresource const& rhs ) const
+    {
+      return ( aspectMask == rhs.aspectMask )
+          && ( mipLevel == rhs.mipLevel )
+          && ( arrayLayer == rhs.arrayLayer );
+    }
+
+    bool operator!=( ImageSubresource const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageAspectFlags aspectMask;
+    uint32_t mipLevel;
+    uint32_t arrayLayer;
+  };
+  static_assert( sizeof( ImageSubresource ) == sizeof( VkImageSubresource ), "struct and wrapper have different size!" );
+
+  struct ImageSubresourceLayers
+  {
+    ImageSubresourceLayers( ImageAspectFlags aspectMask_ = ImageAspectFlags(), uint32_t mipLevel_ = 0, uint32_t baseArrayLayer_ = 0, uint32_t layerCount_ = 0 )
+      : aspectMask( aspectMask_ )
+      , mipLevel( mipLevel_ )
+      , baseArrayLayer( baseArrayLayer_ )
+      , layerCount( layerCount_ )
+    {
+    }
+
+    ImageSubresourceLayers( VkImageSubresourceLayers const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageSubresourceLayers) );
+    }
+
+    ImageSubresourceLayers& operator=( VkImageSubresourceLayers const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageSubresourceLayers) );
+      return *this;
+    }
+
+    ImageSubresourceLayers& setAspectMask( ImageAspectFlags aspectMask_ )
+    {
+      aspectMask = aspectMask_;
+      return *this;
+    }
+
+    ImageSubresourceLayers& setMipLevel( uint32_t mipLevel_ )
+    {
+      mipLevel = mipLevel_;
+      return *this;
+    }
+
+    ImageSubresourceLayers& setBaseArrayLayer( uint32_t baseArrayLayer_ )
+    {
+      baseArrayLayer = baseArrayLayer_;
+      return *this;
+    }
+
+    ImageSubresourceLayers& setLayerCount( uint32_t layerCount_ )
+    {
+      layerCount = layerCount_;
+      return *this;
+    }
+
+    operator const VkImageSubresourceLayers&() const
+    {
+      return *reinterpret_cast<const VkImageSubresourceLayers*>(this);
+    }
+
+    bool operator==( ImageSubresourceLayers const& rhs ) const
+    {
+      return ( aspectMask == rhs.aspectMask )
+          && ( mipLevel == rhs.mipLevel )
+          && ( baseArrayLayer == rhs.baseArrayLayer )
+          && ( layerCount == rhs.layerCount );
+    }
+
+    bool operator!=( ImageSubresourceLayers const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageAspectFlags aspectMask;
+    uint32_t mipLevel;
+    uint32_t baseArrayLayer;
+    uint32_t layerCount;
+  };
+  static_assert( sizeof( ImageSubresourceLayers ) == sizeof( VkImageSubresourceLayers ), "struct and wrapper have different size!" );
+
+  struct ImageSubresourceRange
+  {
+    ImageSubresourceRange( ImageAspectFlags aspectMask_ = ImageAspectFlags(), uint32_t baseMipLevel_ = 0, uint32_t levelCount_ = 0, uint32_t baseArrayLayer_ = 0, uint32_t layerCount_ = 0 )
+      : aspectMask( aspectMask_ )
+      , baseMipLevel( baseMipLevel_ )
+      , levelCount( levelCount_ )
+      , baseArrayLayer( baseArrayLayer_ )
+      , layerCount( layerCount_ )
+    {
+    }
+
+    ImageSubresourceRange( VkImageSubresourceRange const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageSubresourceRange) );
+    }
+
+    ImageSubresourceRange& operator=( VkImageSubresourceRange const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageSubresourceRange) );
+      return *this;
+    }
+
+    ImageSubresourceRange& setAspectMask( ImageAspectFlags aspectMask_ )
+    {
+      aspectMask = aspectMask_;
+      return *this;
+    }
+
+    ImageSubresourceRange& setBaseMipLevel( uint32_t baseMipLevel_ )
+    {
+      baseMipLevel = baseMipLevel_;
+      return *this;
+    }
+
+    ImageSubresourceRange& setLevelCount( uint32_t levelCount_ )
+    {
+      levelCount = levelCount_;
+      return *this;
+    }
+
+    ImageSubresourceRange& setBaseArrayLayer( uint32_t baseArrayLayer_ )
+    {
+      baseArrayLayer = baseArrayLayer_;
+      return *this;
+    }
+
+    ImageSubresourceRange& setLayerCount( uint32_t layerCount_ )
+    {
+      layerCount = layerCount_;
+      return *this;
+    }
+
+    operator const VkImageSubresourceRange&() const
+    {
+      return *reinterpret_cast<const VkImageSubresourceRange*>(this);
+    }
+
+    bool operator==( ImageSubresourceRange const& rhs ) const
+    {
+      return ( aspectMask == rhs.aspectMask )
+          && ( baseMipLevel == rhs.baseMipLevel )
+          && ( levelCount == rhs.levelCount )
+          && ( baseArrayLayer == rhs.baseArrayLayer )
+          && ( layerCount == rhs.layerCount );
+    }
+
+    bool operator!=( ImageSubresourceRange const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageAspectFlags aspectMask;
+    uint32_t baseMipLevel;
+    uint32_t levelCount;
+    uint32_t baseArrayLayer;
+    uint32_t layerCount;
+  };
+  static_assert( sizeof( ImageSubresourceRange ) == sizeof( VkImageSubresourceRange ), "struct and wrapper have different size!" );
+
+  struct ImageMemoryBarrier
+  {
+    ImageMemoryBarrier( AccessFlags srcAccessMask_ = AccessFlags(), AccessFlags dstAccessMask_ = AccessFlags(), ImageLayout oldLayout_ = ImageLayout::eUndefined, ImageLayout newLayout_ = ImageLayout::eUndefined, uint32_t srcQueueFamilyIndex_ = 0, uint32_t dstQueueFamilyIndex_ = 0, Image image_ = Image(), ImageSubresourceRange subresourceRange_ = ImageSubresourceRange() )
+      : sType( StructureType::eImageMemoryBarrier )
+      , pNext( nullptr )
+      , srcAccessMask( srcAccessMask_ )
+      , dstAccessMask( dstAccessMask_ )
+      , oldLayout( oldLayout_ )
+      , newLayout( newLayout_ )
+      , srcQueueFamilyIndex( srcQueueFamilyIndex_ )
+      , dstQueueFamilyIndex( dstQueueFamilyIndex_ )
+      , image( image_ )
+      , subresourceRange( subresourceRange_ )
+    {
+    }
+
+    ImageMemoryBarrier( VkImageMemoryBarrier const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageMemoryBarrier) );
+    }
+
+    ImageMemoryBarrier& operator=( VkImageMemoryBarrier const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageMemoryBarrier) );
+      return *this;
+    }
+
+    ImageMemoryBarrier& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setSrcAccessMask( AccessFlags srcAccessMask_ )
+    {
+      srcAccessMask = srcAccessMask_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setDstAccessMask( AccessFlags dstAccessMask_ )
+    {
+      dstAccessMask = dstAccessMask_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setOldLayout( ImageLayout oldLayout_ )
+    {
+      oldLayout = oldLayout_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setNewLayout( ImageLayout newLayout_ )
+    {
+      newLayout = newLayout_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setSrcQueueFamilyIndex( uint32_t srcQueueFamilyIndex_ )
+    {
+      srcQueueFamilyIndex = srcQueueFamilyIndex_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setDstQueueFamilyIndex( uint32_t dstQueueFamilyIndex_ )
+    {
+      dstQueueFamilyIndex = dstQueueFamilyIndex_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setImage( Image image_ )
+    {
+      image = image_;
+      return *this;
+    }
+
+    ImageMemoryBarrier& setSubresourceRange( ImageSubresourceRange subresourceRange_ )
+    {
+      subresourceRange = subresourceRange_;
+      return *this;
+    }
+
+    operator const VkImageMemoryBarrier&() const
+    {
+      return *reinterpret_cast<const VkImageMemoryBarrier*>(this);
+    }
+
+    bool operator==( ImageMemoryBarrier const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( srcAccessMask == rhs.srcAccessMask )
+          && ( dstAccessMask == rhs.dstAccessMask )
+          && ( oldLayout == rhs.oldLayout )
+          && ( newLayout == rhs.newLayout )
+          && ( srcQueueFamilyIndex == rhs.srcQueueFamilyIndex )
+          && ( dstQueueFamilyIndex == rhs.dstQueueFamilyIndex )
+          && ( image == rhs.image )
+          && ( subresourceRange == rhs.subresourceRange );
+    }
+
+    bool operator!=( ImageMemoryBarrier const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    AccessFlags srcAccessMask;
+    AccessFlags dstAccessMask;
+    ImageLayout oldLayout;
+    ImageLayout newLayout;
+    uint32_t srcQueueFamilyIndex;
+    uint32_t dstQueueFamilyIndex;
+    Image image;
+    ImageSubresourceRange subresourceRange;
+  };
+  static_assert( sizeof( ImageMemoryBarrier ) == sizeof( VkImageMemoryBarrier ), "struct and wrapper have different size!" );
+
+  struct ImageViewCreateInfo
+  {
+    ImageViewCreateInfo( ImageViewCreateFlags flags_ = ImageViewCreateFlags(), Image image_ = Image(), ImageViewType viewType_ = ImageViewType::e1D, Format format_ = Format::eUndefined, ComponentMapping components_ = ComponentMapping(), ImageSubresourceRange subresourceRange_ = ImageSubresourceRange() )
+      : sType( StructureType::eImageViewCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , image( image_ )
+      , viewType( viewType_ )
+      , format( format_ )
+      , components( components_ )
+      , subresourceRange( subresourceRange_ )
+    {
+    }
+
+    ImageViewCreateInfo( VkImageViewCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageViewCreateInfo) );
+    }
+
+    ImageViewCreateInfo& operator=( VkImageViewCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageViewCreateInfo) );
+      return *this;
+    }
+
+    ImageViewCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ImageViewCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ImageViewCreateInfo& setFlags( ImageViewCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    ImageViewCreateInfo& setImage( Image image_ )
+    {
+      image = image_;
+      return *this;
+    }
+
+    ImageViewCreateInfo& setViewType( ImageViewType viewType_ )
+    {
+      viewType = viewType_;
+      return *this;
+    }
+
+    ImageViewCreateInfo& setFormat( Format format_ )
+    {
+      format = format_;
+      return *this;
+    }
+
+    ImageViewCreateInfo& setComponents( ComponentMapping components_ )
+    {
+      components = components_;
+      return *this;
+    }
+
+    ImageViewCreateInfo& setSubresourceRange( ImageSubresourceRange subresourceRange_ )
+    {
+      subresourceRange = subresourceRange_;
+      return *this;
+    }
+
+    operator const VkImageViewCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkImageViewCreateInfo*>(this);
+    }
+
+    bool operator==( ImageViewCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( image == rhs.image )
+          && ( viewType == rhs.viewType )
+          && ( format == rhs.format )
+          && ( components == rhs.components )
+          && ( subresourceRange == rhs.subresourceRange );
+    }
+
+    bool operator!=( ImageViewCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    ImageViewCreateFlags flags;
+    Image image;
+    ImageViewType viewType;
+    Format format;
+    ComponentMapping components;
+    ImageSubresourceRange subresourceRange;
+  };
+  static_assert( sizeof( ImageViewCreateInfo ) == sizeof( VkImageViewCreateInfo ), "struct and wrapper have different size!" );
+
+  struct ImageCopy
+  {
+    ImageCopy( ImageSubresourceLayers srcSubresource_ = ImageSubresourceLayers(), Offset3D srcOffset_ = Offset3D(), ImageSubresourceLayers dstSubresource_ = ImageSubresourceLayers(), Offset3D dstOffset_ = Offset3D(), Extent3D extent_ = Extent3D() )
+      : srcSubresource( srcSubresource_ )
+      , srcOffset( srcOffset_ )
+      , dstSubresource( dstSubresource_ )
+      , dstOffset( dstOffset_ )
+      , extent( extent_ )
+    {
+    }
+
+    ImageCopy( VkImageCopy const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageCopy) );
+    }
+
+    ImageCopy& operator=( VkImageCopy const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageCopy) );
+      return *this;
+    }
+
+    ImageCopy& setSrcSubresource( ImageSubresourceLayers srcSubresource_ )
+    {
+      srcSubresource = srcSubresource_;
+      return *this;
+    }
+
+    ImageCopy& setSrcOffset( Offset3D srcOffset_ )
+    {
+      srcOffset = srcOffset_;
+      return *this;
+    }
+
+    ImageCopy& setDstSubresource( ImageSubresourceLayers dstSubresource_ )
+    {
+      dstSubresource = dstSubresource_;
+      return *this;
+    }
+
+    ImageCopy& setDstOffset( Offset3D dstOffset_ )
+    {
+      dstOffset = dstOffset_;
+      return *this;
+    }
+
+    ImageCopy& setExtent( Extent3D extent_ )
+    {
+      extent = extent_;
+      return *this;
+    }
+
+    operator const VkImageCopy&() const
+    {
+      return *reinterpret_cast<const VkImageCopy*>(this);
+    }
+
+    bool operator==( ImageCopy const& rhs ) const
+    {
+      return ( srcSubresource == rhs.srcSubresource )
+          && ( srcOffset == rhs.srcOffset )
+          && ( dstSubresource == rhs.dstSubresource )
+          && ( dstOffset == rhs.dstOffset )
+          && ( extent == rhs.extent );
+    }
+
+    bool operator!=( ImageCopy const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageSubresourceLayers srcSubresource;
+    Offset3D srcOffset;
+    ImageSubresourceLayers dstSubresource;
+    Offset3D dstOffset;
+    Extent3D extent;
+  };
+  static_assert( sizeof( ImageCopy ) == sizeof( VkImageCopy ), "struct and wrapper have different size!" );
+
+  struct ImageBlit
+  {
+    ImageBlit( ImageSubresourceLayers srcSubresource_ = ImageSubresourceLayers(), std::array<Offset3D,2> const& srcOffsets_ = { { Offset3D(), Offset3D() } }, ImageSubresourceLayers dstSubresource_ = ImageSubresourceLayers(), std::array<Offset3D,2> const& dstOffsets_ = { { Offset3D(), Offset3D() } } )
+      : srcSubresource( srcSubresource_ )
+      , dstSubresource( dstSubresource_ )
+    {
+      memcpy( &srcOffsets, srcOffsets_.data(), 2 * sizeof( Offset3D ) );
+      memcpy( &dstOffsets, dstOffsets_.data(), 2 * sizeof( Offset3D ) );
+    }
+
+    ImageBlit( VkImageBlit const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageBlit) );
+    }
+
+    ImageBlit& operator=( VkImageBlit const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageBlit) );
+      return *this;
+    }
+
+    ImageBlit& setSrcSubresource( ImageSubresourceLayers srcSubresource_ )
+    {
+      srcSubresource = srcSubresource_;
+      return *this;
+    }
+
+    ImageBlit& setSrcOffsets( std::array<Offset3D,2> srcOffsets_ )
+    {
+      memcpy( &srcOffsets, srcOffsets_.data(), 2 * sizeof( Offset3D ) );
+      return *this;
+    }
+
+    ImageBlit& setDstSubresource( ImageSubresourceLayers dstSubresource_ )
+    {
+      dstSubresource = dstSubresource_;
+      return *this;
+    }
+
+    ImageBlit& setDstOffsets( std::array<Offset3D,2> dstOffsets_ )
+    {
+      memcpy( &dstOffsets, dstOffsets_.data(), 2 * sizeof( Offset3D ) );
+      return *this;
+    }
+
+    operator const VkImageBlit&() const
+    {
+      return *reinterpret_cast<const VkImageBlit*>(this);
+    }
+
+    bool operator==( ImageBlit const& rhs ) const
+    {
+      return ( srcSubresource == rhs.srcSubresource )
+          && ( memcmp( srcOffsets, rhs.srcOffsets, 2 * sizeof( Offset3D ) ) == 0 )
+          && ( dstSubresource == rhs.dstSubresource )
+          && ( memcmp( dstOffsets, rhs.dstOffsets, 2 * sizeof( Offset3D ) ) == 0 );
+    }
+
+    bool operator!=( ImageBlit const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageSubresourceLayers srcSubresource;
+    Offset3D srcOffsets[2];
+    ImageSubresourceLayers dstSubresource;
+    Offset3D dstOffsets[2];
+  };
+  static_assert( sizeof( ImageBlit ) == sizeof( VkImageBlit ), "struct and wrapper have different size!" );
+
+  struct BufferImageCopy
+  {
+    BufferImageCopy( DeviceSize bufferOffset_ = 0, uint32_t bufferRowLength_ = 0, uint32_t bufferImageHeight_ = 0, ImageSubresourceLayers imageSubresource_ = ImageSubresourceLayers(), Offset3D imageOffset_ = Offset3D(), Extent3D imageExtent_ = Extent3D() )
+      : bufferOffset( bufferOffset_ )
+      , bufferRowLength( bufferRowLength_ )
+      , bufferImageHeight( bufferImageHeight_ )
+      , imageSubresource( imageSubresource_ )
+      , imageOffset( imageOffset_ )
+      , imageExtent( imageExtent_ )
+    {
+    }
+
+    BufferImageCopy( VkBufferImageCopy const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferImageCopy) );
+    }
+
+    BufferImageCopy& operator=( VkBufferImageCopy const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BufferImageCopy) );
+      return *this;
+    }
+
+    BufferImageCopy& setBufferOffset( DeviceSize bufferOffset_ )
+    {
+      bufferOffset = bufferOffset_;
+      return *this;
+    }
+
+    BufferImageCopy& setBufferRowLength( uint32_t bufferRowLength_ )
+    {
+      bufferRowLength = bufferRowLength_;
+      return *this;
+    }
+
+    BufferImageCopy& setBufferImageHeight( uint32_t bufferImageHeight_ )
+    {
+      bufferImageHeight = bufferImageHeight_;
+      return *this;
+    }
+
+    BufferImageCopy& setImageSubresource( ImageSubresourceLayers imageSubresource_ )
+    {
+      imageSubresource = imageSubresource_;
+      return *this;
+    }
+
+    BufferImageCopy& setImageOffset( Offset3D imageOffset_ )
+    {
+      imageOffset = imageOffset_;
+      return *this;
+    }
+
+    BufferImageCopy& setImageExtent( Extent3D imageExtent_ )
+    {
+      imageExtent = imageExtent_;
+      return *this;
+    }
+
+    operator const VkBufferImageCopy&() const
+    {
+      return *reinterpret_cast<const VkBufferImageCopy*>(this);
+    }
+
+    bool operator==( BufferImageCopy const& rhs ) const
+    {
+      return ( bufferOffset == rhs.bufferOffset )
+          && ( bufferRowLength == rhs.bufferRowLength )
+          && ( bufferImageHeight == rhs.bufferImageHeight )
+          && ( imageSubresource == rhs.imageSubresource )
+          && ( imageOffset == rhs.imageOffset )
+          && ( imageExtent == rhs.imageExtent );
+    }
+
+    bool operator!=( BufferImageCopy const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DeviceSize bufferOffset;
+    uint32_t bufferRowLength;
+    uint32_t bufferImageHeight;
+    ImageSubresourceLayers imageSubresource;
+    Offset3D imageOffset;
+    Extent3D imageExtent;
+  };
+  static_assert( sizeof( BufferImageCopy ) == sizeof( VkBufferImageCopy ), "struct and wrapper have different size!" );
+
+  struct ImageResolve
+  {
+    ImageResolve( ImageSubresourceLayers srcSubresource_ = ImageSubresourceLayers(), Offset3D srcOffset_ = Offset3D(), ImageSubresourceLayers dstSubresource_ = ImageSubresourceLayers(), Offset3D dstOffset_ = Offset3D(), Extent3D extent_ = Extent3D() )
+      : srcSubresource( srcSubresource_ )
+      , srcOffset( srcOffset_ )
+      , dstSubresource( dstSubresource_ )
+      , dstOffset( dstOffset_ )
+      , extent( extent_ )
+    {
+    }
+
+    ImageResolve( VkImageResolve const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageResolve) );
+    }
+
+    ImageResolve& operator=( VkImageResolve const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageResolve) );
+      return *this;
+    }
+
+    ImageResolve& setSrcSubresource( ImageSubresourceLayers srcSubresource_ )
+    {
+      srcSubresource = srcSubresource_;
+      return *this;
+    }
+
+    ImageResolve& setSrcOffset( Offset3D srcOffset_ )
+    {
+      srcOffset = srcOffset_;
+      return *this;
+    }
+
+    ImageResolve& setDstSubresource( ImageSubresourceLayers dstSubresource_ )
+    {
+      dstSubresource = dstSubresource_;
+      return *this;
+    }
+
+    ImageResolve& setDstOffset( Offset3D dstOffset_ )
+    {
+      dstOffset = dstOffset_;
+      return *this;
+    }
+
+    ImageResolve& setExtent( Extent3D extent_ )
+    {
+      extent = extent_;
+      return *this;
+    }
+
+    operator const VkImageResolve&() const
+    {
+      return *reinterpret_cast<const VkImageResolve*>(this);
+    }
+
+    bool operator==( ImageResolve const& rhs ) const
+    {
+      return ( srcSubresource == rhs.srcSubresource )
+          && ( srcOffset == rhs.srcOffset )
+          && ( dstSubresource == rhs.dstSubresource )
+          && ( dstOffset == rhs.dstOffset )
+          && ( extent == rhs.extent );
+    }
+
+    bool operator!=( ImageResolve const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageSubresourceLayers srcSubresource;
+    Offset3D srcOffset;
+    ImageSubresourceLayers dstSubresource;
+    Offset3D dstOffset;
+    Extent3D extent;
+  };
+  static_assert( sizeof( ImageResolve ) == sizeof( VkImageResolve ), "struct and wrapper have different size!" );
+
+  struct ClearAttachment
+  {
+    ClearAttachment( ImageAspectFlags aspectMask_ = ImageAspectFlags(), uint32_t colorAttachment_ = 0, ClearValue clearValue_ = ClearValue() )
+      : aspectMask( aspectMask_ )
+      , colorAttachment( colorAttachment_ )
+      , clearValue( clearValue_ )
+    {
+    }
+
+    ClearAttachment( VkClearAttachment const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ClearAttachment) );
+    }
+
+    ClearAttachment& operator=( VkClearAttachment const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ClearAttachment) );
+      return *this;
+    }
+
+    ClearAttachment& setAspectMask( ImageAspectFlags aspectMask_ )
+    {
+      aspectMask = aspectMask_;
+      return *this;
+    }
+
+    ClearAttachment& setColorAttachment( uint32_t colorAttachment_ )
+    {
+      colorAttachment = colorAttachment_;
+      return *this;
+    }
+
+    ClearAttachment& setClearValue( ClearValue clearValue_ )
+    {
+      clearValue = clearValue_;
+      return *this;
+    }
+
+    operator const VkClearAttachment&() const
+    {
+      return *reinterpret_cast<const VkClearAttachment*>(this);
+    }
+
+    ImageAspectFlags aspectMask;
+    uint32_t colorAttachment;
+    ClearValue clearValue;
+  };
+  static_assert( sizeof( ClearAttachment ) == sizeof( VkClearAttachment ), "struct and wrapper have different size!" );
+
+  enum class SparseImageFormatFlagBits
+  {
+    eSingleMiptail = VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT,
+    eAlignedMipSize = VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT,
+    eNonstandardBlockSize = VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT
+  };
+
+  using SparseImageFormatFlags = Flags<SparseImageFormatFlagBits, VkSparseImageFormatFlags>;
+
+  inline SparseImageFormatFlags operator|( SparseImageFormatFlagBits bit0, SparseImageFormatFlagBits bit1 )
+  {
+    return SparseImageFormatFlags( bit0 ) | bit1;
+  }
+
+  struct SparseImageFormatProperties
+  {
+    operator const VkSparseImageFormatProperties&() const
+    {
+      return *reinterpret_cast<const VkSparseImageFormatProperties*>(this);
+    }
+
+    bool operator==( SparseImageFormatProperties const& rhs ) const
+    {
+      return ( aspectMask == rhs.aspectMask )
+          && ( imageGranularity == rhs.imageGranularity )
+          && ( flags == rhs.flags );
+    }
+
+    bool operator!=( SparseImageFormatProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageAspectFlags aspectMask;
+    Extent3D imageGranularity;
+    SparseImageFormatFlags flags;
+  };
+  static_assert( sizeof( SparseImageFormatProperties ) == sizeof( VkSparseImageFormatProperties ), "struct and wrapper have different size!" );
+
+  struct SparseImageMemoryRequirements
+  {
+    operator const VkSparseImageMemoryRequirements&() const
+    {
+      return *reinterpret_cast<const VkSparseImageMemoryRequirements*>(this);
+    }
+
+    bool operator==( SparseImageMemoryRequirements const& rhs ) const
+    {
+      return ( formatProperties == rhs.formatProperties )
+          && ( imageMipTailFirstLod == rhs.imageMipTailFirstLod )
+          && ( imageMipTailSize == rhs.imageMipTailSize )
+          && ( imageMipTailOffset == rhs.imageMipTailOffset )
+          && ( imageMipTailStride == rhs.imageMipTailStride );
+    }
+
+    bool operator!=( SparseImageMemoryRequirements const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    SparseImageFormatProperties formatProperties;
+    uint32_t imageMipTailFirstLod;
+    DeviceSize imageMipTailSize;
+    DeviceSize imageMipTailOffset;
+    DeviceSize imageMipTailStride;
+  };
+  static_assert( sizeof( SparseImageMemoryRequirements ) == sizeof( VkSparseImageMemoryRequirements ), "struct and wrapper have different size!" );
+
+  enum class SparseMemoryBindFlagBits
+  {
+    eMetadata = VK_SPARSE_MEMORY_BIND_METADATA_BIT
+  };
+
+  using SparseMemoryBindFlags = Flags<SparseMemoryBindFlagBits, VkSparseMemoryBindFlags>;
+
+  inline SparseMemoryBindFlags operator|( SparseMemoryBindFlagBits bit0, SparseMemoryBindFlagBits bit1 )
+  {
+    return SparseMemoryBindFlags( bit0 ) | bit1;
+  }
+
+  struct SparseMemoryBind
+  {
+    SparseMemoryBind( DeviceSize resourceOffset_ = 0, DeviceSize size_ = 0, DeviceMemory memory_ = DeviceMemory(), DeviceSize memoryOffset_ = 0, SparseMemoryBindFlags flags_ = SparseMemoryBindFlags() )
+      : resourceOffset( resourceOffset_ )
+      , size( size_ )
+      , memory( memory_ )
+      , memoryOffset( memoryOffset_ )
+      , flags( flags_ )
+    {
+    }
+
+    SparseMemoryBind( VkSparseMemoryBind const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseMemoryBind) );
+    }
+
+    SparseMemoryBind& operator=( VkSparseMemoryBind const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseMemoryBind) );
+      return *this;
+    }
+
+    SparseMemoryBind& setResourceOffset( DeviceSize resourceOffset_ )
+    {
+      resourceOffset = resourceOffset_;
+      return *this;
+    }
+
+    SparseMemoryBind& setSize( DeviceSize size_ )
+    {
+      size = size_;
+      return *this;
+    }
+
+    SparseMemoryBind& setMemory( DeviceMemory memory_ )
+    {
+      memory = memory_;
+      return *this;
+    }
+
+    SparseMemoryBind& setMemoryOffset( DeviceSize memoryOffset_ )
+    {
+      memoryOffset = memoryOffset_;
+      return *this;
+    }
+
+    SparseMemoryBind& setFlags( SparseMemoryBindFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    operator const VkSparseMemoryBind&() const
+    {
+      return *reinterpret_cast<const VkSparseMemoryBind*>(this);
+    }
+
+    bool operator==( SparseMemoryBind const& rhs ) const
+    {
+      return ( resourceOffset == rhs.resourceOffset )
+          && ( size == rhs.size )
+          && ( memory == rhs.memory )
+          && ( memoryOffset == rhs.memoryOffset )
+          && ( flags == rhs.flags );
+    }
+
+    bool operator!=( SparseMemoryBind const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DeviceSize resourceOffset;
+    DeviceSize size;
+    DeviceMemory memory;
+    DeviceSize memoryOffset;
+    SparseMemoryBindFlags flags;
+  };
+  static_assert( sizeof( SparseMemoryBind ) == sizeof( VkSparseMemoryBind ), "struct and wrapper have different size!" );
+
+  struct SparseImageMemoryBind
+  {
+    SparseImageMemoryBind( ImageSubresource subresource_ = ImageSubresource(), Offset3D offset_ = Offset3D(), Extent3D extent_ = Extent3D(), DeviceMemory memory_ = DeviceMemory(), DeviceSize memoryOffset_ = 0, SparseMemoryBindFlags flags_ = SparseMemoryBindFlags() )
+      : subresource( subresource_ )
+      , offset( offset_ )
+      , extent( extent_ )
+      , memory( memory_ )
+      , memoryOffset( memoryOffset_ )
+      , flags( flags_ )
+    {
+    }
+
+    SparseImageMemoryBind( VkSparseImageMemoryBind const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseImageMemoryBind) );
+    }
+
+    SparseImageMemoryBind& operator=( VkSparseImageMemoryBind const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseImageMemoryBind) );
+      return *this;
+    }
+
+    SparseImageMemoryBind& setSubresource( ImageSubresource subresource_ )
+    {
+      subresource = subresource_;
+      return *this;
+    }
+
+    SparseImageMemoryBind& setOffset( Offset3D offset_ )
+    {
+      offset = offset_;
+      return *this;
+    }
+
+    SparseImageMemoryBind& setExtent( Extent3D extent_ )
+    {
+      extent = extent_;
+      return *this;
+    }
+
+    SparseImageMemoryBind& setMemory( DeviceMemory memory_ )
+    {
+      memory = memory_;
+      return *this;
+    }
+
+    SparseImageMemoryBind& setMemoryOffset( DeviceSize memoryOffset_ )
+    {
+      memoryOffset = memoryOffset_;
+      return *this;
+    }
+
+    SparseImageMemoryBind& setFlags( SparseMemoryBindFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    operator const VkSparseImageMemoryBind&() const
+    {
+      return *reinterpret_cast<const VkSparseImageMemoryBind*>(this);
+    }
+
+    bool operator==( SparseImageMemoryBind const& rhs ) const
+    {
+      return ( subresource == rhs.subresource )
+          && ( offset == rhs.offset )
+          && ( extent == rhs.extent )
+          && ( memory == rhs.memory )
+          && ( memoryOffset == rhs.memoryOffset )
+          && ( flags == rhs.flags );
+    }
+
+    bool operator!=( SparseImageMemoryBind const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageSubresource subresource;
+    Offset3D offset;
+    Extent3D extent;
+    DeviceMemory memory;
+    DeviceSize memoryOffset;
+    SparseMemoryBindFlags flags;
+  };
+  static_assert( sizeof( SparseImageMemoryBind ) == sizeof( VkSparseImageMemoryBind ), "struct and wrapper have different size!" );
+
+  struct SparseBufferMemoryBindInfo
+  {
+    SparseBufferMemoryBindInfo( Buffer buffer_ = Buffer(), uint32_t bindCount_ = 0, const SparseMemoryBind* pBinds_ = nullptr )
+      : buffer( buffer_ )
+      , bindCount( bindCount_ )
+      , pBinds( pBinds_ )
+    {
+    }
+
+    SparseBufferMemoryBindInfo( VkSparseBufferMemoryBindInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseBufferMemoryBindInfo) );
+    }
+
+    SparseBufferMemoryBindInfo& operator=( VkSparseBufferMemoryBindInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseBufferMemoryBindInfo) );
+      return *this;
+    }
+
+    SparseBufferMemoryBindInfo& setBuffer( Buffer buffer_ )
+    {
+      buffer = buffer_;
+      return *this;
+    }
+
+    SparseBufferMemoryBindInfo& setBindCount( uint32_t bindCount_ )
+    {
+      bindCount = bindCount_;
+      return *this;
+    }
+
+    SparseBufferMemoryBindInfo& setPBinds( const SparseMemoryBind* pBinds_ )
+    {
+      pBinds = pBinds_;
+      return *this;
+    }
+
+    operator const VkSparseBufferMemoryBindInfo&() const
+    {
+      return *reinterpret_cast<const VkSparseBufferMemoryBindInfo*>(this);
+    }
+
+    bool operator==( SparseBufferMemoryBindInfo const& rhs ) const
+    {
+      return ( buffer == rhs.buffer )
+          && ( bindCount == rhs.bindCount )
+          && ( pBinds == rhs.pBinds );
+    }
+
+    bool operator!=( SparseBufferMemoryBindInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Buffer buffer;
+    uint32_t bindCount;
+    const SparseMemoryBind* pBinds;
+  };
+  static_assert( sizeof( SparseBufferMemoryBindInfo ) == sizeof( VkSparseBufferMemoryBindInfo ), "struct and wrapper have different size!" );
+
+  struct SparseImageOpaqueMemoryBindInfo
+  {
+    SparseImageOpaqueMemoryBindInfo( Image image_ = Image(), uint32_t bindCount_ = 0, const SparseMemoryBind* pBinds_ = nullptr )
+      : image( image_ )
+      , bindCount( bindCount_ )
+      , pBinds( pBinds_ )
+    {
+    }
+
+    SparseImageOpaqueMemoryBindInfo( VkSparseImageOpaqueMemoryBindInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseImageOpaqueMemoryBindInfo) );
+    }
+
+    SparseImageOpaqueMemoryBindInfo& operator=( VkSparseImageOpaqueMemoryBindInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseImageOpaqueMemoryBindInfo) );
+      return *this;
+    }
+
+    SparseImageOpaqueMemoryBindInfo& setImage( Image image_ )
+    {
+      image = image_;
+      return *this;
+    }
+
+    SparseImageOpaqueMemoryBindInfo& setBindCount( uint32_t bindCount_ )
+    {
+      bindCount = bindCount_;
+      return *this;
+    }
+
+    SparseImageOpaqueMemoryBindInfo& setPBinds( const SparseMemoryBind* pBinds_ )
+    {
+      pBinds = pBinds_;
+      return *this;
+    }
+
+    operator const VkSparseImageOpaqueMemoryBindInfo&() const
+    {
+      return *reinterpret_cast<const VkSparseImageOpaqueMemoryBindInfo*>(this);
+    }
+
+    bool operator==( SparseImageOpaqueMemoryBindInfo const& rhs ) const
+    {
+      return ( image == rhs.image )
+          && ( bindCount == rhs.bindCount )
+          && ( pBinds == rhs.pBinds );
+    }
+
+    bool operator!=( SparseImageOpaqueMemoryBindInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Image image;
+    uint32_t bindCount;
+    const SparseMemoryBind* pBinds;
+  };
+  static_assert( sizeof( SparseImageOpaqueMemoryBindInfo ) == sizeof( VkSparseImageOpaqueMemoryBindInfo ), "struct and wrapper have different size!" );
+
+  struct SparseImageMemoryBindInfo
+  {
+    SparseImageMemoryBindInfo( Image image_ = Image(), uint32_t bindCount_ = 0, const SparseImageMemoryBind* pBinds_ = nullptr )
+      : image( image_ )
+      , bindCount( bindCount_ )
+      , pBinds( pBinds_ )
+    {
+    }
+
+    SparseImageMemoryBindInfo( VkSparseImageMemoryBindInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseImageMemoryBindInfo) );
+    }
+
+    SparseImageMemoryBindInfo& operator=( VkSparseImageMemoryBindInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SparseImageMemoryBindInfo) );
+      return *this;
+    }
+
+    SparseImageMemoryBindInfo& setImage( Image image_ )
+    {
+      image = image_;
+      return *this;
+    }
+
+    SparseImageMemoryBindInfo& setBindCount( uint32_t bindCount_ )
+    {
+      bindCount = bindCount_;
+      return *this;
+    }
+
+    SparseImageMemoryBindInfo& setPBinds( const SparseImageMemoryBind* pBinds_ )
+    {
+      pBinds = pBinds_;
+      return *this;
+    }
+
+    operator const VkSparseImageMemoryBindInfo&() const
+    {
+      return *reinterpret_cast<const VkSparseImageMemoryBindInfo*>(this);
+    }
+
+    bool operator==( SparseImageMemoryBindInfo const& rhs ) const
+    {
+      return ( image == rhs.image )
+          && ( bindCount == rhs.bindCount )
+          && ( pBinds == rhs.pBinds );
+    }
+
+    bool operator!=( SparseImageMemoryBindInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Image image;
+    uint32_t bindCount;
+    const SparseImageMemoryBind* pBinds;
+  };
+  static_assert( sizeof( SparseImageMemoryBindInfo ) == sizeof( VkSparseImageMemoryBindInfo ), "struct and wrapper have different size!" );
+
+  struct BindSparseInfo
+  {
+    BindSparseInfo( uint32_t waitSemaphoreCount_ = 0, const Semaphore* pWaitSemaphores_ = nullptr, uint32_t bufferBindCount_ = 0, const SparseBufferMemoryBindInfo* pBufferBinds_ = nullptr, uint32_t imageOpaqueBindCount_ = 0, const SparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds_ = nullptr, uint32_t imageBindCount_ = 0, const SparseImageMemoryBindInfo* pImageBinds_ = nullptr, uint32_t signalSemaphoreCount_ = 0, const Semaphore* pSignalSemaphores_ = nullptr )
+      : sType( StructureType::eBindSparseInfo )
+      , pNext( nullptr )
+      , waitSemaphoreCount( waitSemaphoreCount_ )
+      , pWaitSemaphores( pWaitSemaphores_ )
+      , bufferBindCount( bufferBindCount_ )
+      , pBufferBinds( pBufferBinds_ )
+      , imageOpaqueBindCount( imageOpaqueBindCount_ )
+      , pImageOpaqueBinds( pImageOpaqueBinds_ )
+      , imageBindCount( imageBindCount_ )
+      , pImageBinds( pImageBinds_ )
+      , signalSemaphoreCount( signalSemaphoreCount_ )
+      , pSignalSemaphores( pSignalSemaphores_ )
+    {
+    }
+
+    BindSparseInfo( VkBindSparseInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BindSparseInfo) );
+    }
+
+    BindSparseInfo& operator=( VkBindSparseInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(BindSparseInfo) );
+      return *this;
+    }
+
+    BindSparseInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    BindSparseInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    BindSparseInfo& setWaitSemaphoreCount( uint32_t waitSemaphoreCount_ )
+    {
+      waitSemaphoreCount = waitSemaphoreCount_;
+      return *this;
+    }
+
+    BindSparseInfo& setPWaitSemaphores( const Semaphore* pWaitSemaphores_ )
+    {
+      pWaitSemaphores = pWaitSemaphores_;
+      return *this;
+    }
+
+    BindSparseInfo& setBufferBindCount( uint32_t bufferBindCount_ )
+    {
+      bufferBindCount = bufferBindCount_;
+      return *this;
+    }
+
+    BindSparseInfo& setPBufferBinds( const SparseBufferMemoryBindInfo* pBufferBinds_ )
+    {
+      pBufferBinds = pBufferBinds_;
+      return *this;
+    }
+
+    BindSparseInfo& setImageOpaqueBindCount( uint32_t imageOpaqueBindCount_ )
+    {
+      imageOpaqueBindCount = imageOpaqueBindCount_;
+      return *this;
+    }
+
+    BindSparseInfo& setPImageOpaqueBinds( const SparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds_ )
+    {
+      pImageOpaqueBinds = pImageOpaqueBinds_;
+      return *this;
+    }
+
+    BindSparseInfo& setImageBindCount( uint32_t imageBindCount_ )
+    {
+      imageBindCount = imageBindCount_;
+      return *this;
+    }
+
+    BindSparseInfo& setPImageBinds( const SparseImageMemoryBindInfo* pImageBinds_ )
+    {
+      pImageBinds = pImageBinds_;
+      return *this;
+    }
+
+    BindSparseInfo& setSignalSemaphoreCount( uint32_t signalSemaphoreCount_ )
+    {
+      signalSemaphoreCount = signalSemaphoreCount_;
+      return *this;
+    }
+
+    BindSparseInfo& setPSignalSemaphores( const Semaphore* pSignalSemaphores_ )
+    {
+      pSignalSemaphores = pSignalSemaphores_;
+      return *this;
+    }
+
+    operator const VkBindSparseInfo&() const
+    {
+      return *reinterpret_cast<const VkBindSparseInfo*>(this);
+    }
+
+    bool operator==( BindSparseInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( waitSemaphoreCount == rhs.waitSemaphoreCount )
+          && ( pWaitSemaphores == rhs.pWaitSemaphores )
+          && ( bufferBindCount == rhs.bufferBindCount )
+          && ( pBufferBinds == rhs.pBufferBinds )
+          && ( imageOpaqueBindCount == rhs.imageOpaqueBindCount )
+          && ( pImageOpaqueBinds == rhs.pImageOpaqueBinds )
+          && ( imageBindCount == rhs.imageBindCount )
+          && ( pImageBinds == rhs.pImageBinds )
+          && ( signalSemaphoreCount == rhs.signalSemaphoreCount )
+          && ( pSignalSemaphores == rhs.pSignalSemaphores );
+    }
+
+    bool operator!=( BindSparseInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    uint32_t waitSemaphoreCount;
+    const Semaphore* pWaitSemaphores;
+    uint32_t bufferBindCount;
+    const SparseBufferMemoryBindInfo* pBufferBinds;
+    uint32_t imageOpaqueBindCount;
+    const SparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds;
+    uint32_t imageBindCount;
+    const SparseImageMemoryBindInfo* pImageBinds;
+    uint32_t signalSemaphoreCount;
+    const Semaphore* pSignalSemaphores;
+  };
+  static_assert( sizeof( BindSparseInfo ) == sizeof( VkBindSparseInfo ), "struct and wrapper have different size!" );
+
+  enum class PipelineStageFlagBits
+  {
+    eTopOfPipe = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+    eDrawIndirect = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
+    eVertexInput = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
+    eVertexShader = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
+    eTessellationControlShader = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT,
+    eTessellationEvaluationShader = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT,
+    eGeometryShader = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
+    eFragmentShader = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+    eEarlyFragmentTests = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
+    eLateFragmentTests = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+    eColorAttachmentOutput = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+    eComputeShader = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
+    eTransfer = VK_PIPELINE_STAGE_TRANSFER_BIT,
+    eBottomOfPipe = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+    eHost = VK_PIPELINE_STAGE_HOST_BIT,
+    eAllGraphics = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
+    eAllCommands = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
+  };
+
+  using PipelineStageFlags = Flags<PipelineStageFlagBits, VkPipelineStageFlags>;
+
+  inline PipelineStageFlags operator|( PipelineStageFlagBits bit0, PipelineStageFlagBits bit1 )
+  {
+    return PipelineStageFlags( bit0 ) | bit1;
+  }
+
+  enum class CommandPoolCreateFlagBits
+  {
+    eTransient = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
+    eResetCommandBuffer = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
+  };
+
+  using CommandPoolCreateFlags = Flags<CommandPoolCreateFlagBits, VkCommandPoolCreateFlags>;
+
+  inline CommandPoolCreateFlags operator|( CommandPoolCreateFlagBits bit0, CommandPoolCreateFlagBits bit1 )
+  {
+    return CommandPoolCreateFlags( bit0 ) | bit1;
+  }
+
+  struct CommandPoolCreateInfo
+  {
+    CommandPoolCreateInfo( CommandPoolCreateFlags flags_ = CommandPoolCreateFlags(), uint32_t queueFamilyIndex_ = 0 )
+      : sType( StructureType::eCommandPoolCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , queueFamilyIndex( queueFamilyIndex_ )
+    {
+    }
+
+    CommandPoolCreateInfo( VkCommandPoolCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CommandPoolCreateInfo) );
+    }
+
+    CommandPoolCreateInfo& operator=( VkCommandPoolCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(CommandPoolCreateInfo) );
+      return *this;
+    }
+
+    CommandPoolCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    CommandPoolCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    CommandPoolCreateInfo& setFlags( CommandPoolCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    CommandPoolCreateInfo& setQueueFamilyIndex( uint32_t queueFamilyIndex_ )
+    {
+      queueFamilyIndex = queueFamilyIndex_;
+      return *this;
+    }
+
+    operator const VkCommandPoolCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkCommandPoolCreateInfo*>(this);
+    }
+
+    bool operator==( CommandPoolCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( queueFamilyIndex == rhs.queueFamilyIndex );
+    }
+
+    bool operator!=( CommandPoolCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    CommandPoolCreateFlags flags;
+    uint32_t queueFamilyIndex;
+  };
+  static_assert( sizeof( CommandPoolCreateInfo ) == sizeof( VkCommandPoolCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class CommandPoolResetFlagBits
+  {
+    eReleaseResources = VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT
+  };
+
+  using CommandPoolResetFlags = Flags<CommandPoolResetFlagBits, VkCommandPoolResetFlags>;
+
+  inline CommandPoolResetFlags operator|( CommandPoolResetFlagBits bit0, CommandPoolResetFlagBits bit1 )
+  {
+    return CommandPoolResetFlags( bit0 ) | bit1;
+  }
+
+  enum class CommandBufferResetFlagBits
+  {
+    eReleaseResources = VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT
+  };
+
+  using CommandBufferResetFlags = Flags<CommandBufferResetFlagBits, VkCommandBufferResetFlags>;
+
+  inline CommandBufferResetFlags operator|( CommandBufferResetFlagBits bit0, CommandBufferResetFlagBits bit1 )
+  {
+    return CommandBufferResetFlags( bit0 ) | bit1;
+  }
+
+  enum class SampleCountFlagBits
+  {
+    e1 = VK_SAMPLE_COUNT_1_BIT,
+    e2 = VK_SAMPLE_COUNT_2_BIT,
+    e4 = VK_SAMPLE_COUNT_4_BIT,
+    e8 = VK_SAMPLE_COUNT_8_BIT,
+    e16 = VK_SAMPLE_COUNT_16_BIT,
+    e32 = VK_SAMPLE_COUNT_32_BIT,
+    e64 = VK_SAMPLE_COUNT_64_BIT
+  };
+
+  using SampleCountFlags = Flags<SampleCountFlagBits, VkSampleCountFlags>;
+
+  inline SampleCountFlags operator|( SampleCountFlagBits bit0, SampleCountFlagBits bit1 )
+  {
+    return SampleCountFlags( bit0 ) | bit1;
+  }
+
+  struct ImageFormatProperties
+  {
+    operator const VkImageFormatProperties&() const
+    {
+      return *reinterpret_cast<const VkImageFormatProperties*>(this);
+    }
+
+    bool operator==( ImageFormatProperties const& rhs ) const
+    {
+      return ( maxExtent == rhs.maxExtent )
+          && ( maxMipLevels == rhs.maxMipLevels )
+          && ( maxArrayLayers == rhs.maxArrayLayers )
+          && ( sampleCounts == rhs.sampleCounts )
+          && ( maxResourceSize == rhs.maxResourceSize );
+    }
+
+    bool operator!=( ImageFormatProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Extent3D maxExtent;
+    uint32_t maxMipLevels;
+    uint32_t maxArrayLayers;
+    SampleCountFlags sampleCounts;
+    DeviceSize maxResourceSize;
+  };
+  static_assert( sizeof( ImageFormatProperties ) == sizeof( VkImageFormatProperties ), "struct and wrapper have different size!" );
+
+  struct ImageCreateInfo
+  {
+    ImageCreateInfo( ImageCreateFlags flags_ = ImageCreateFlags(), ImageType imageType_ = ImageType::e1D, Format format_ = Format::eUndefined, Extent3D extent_ = Extent3D(), uint32_t mipLevels_ = 0, uint32_t arrayLayers_ = 0, SampleCountFlagBits samples_ = SampleCountFlagBits::e1, ImageTiling tiling_ = ImageTiling::eOptimal, ImageUsageFlags usage_ = ImageUsageFlags(), SharingMode sharingMode_ = SharingMode::eExclusive, uint32_t queueFamilyIndexCount_ = 0, const uint32_t* pQueueFamilyIndices_ = nullptr, ImageLayout initialLayout_ = ImageLayout::eUndefined )
+      : sType( StructureType::eImageCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , imageType( imageType_ )
+      , format( format_ )
+      , extent( extent_ )
+      , mipLevels( mipLevels_ )
+      , arrayLayers( arrayLayers_ )
+      , samples( samples_ )
+      , tiling( tiling_ )
+      , usage( usage_ )
+      , sharingMode( sharingMode_ )
+      , queueFamilyIndexCount( queueFamilyIndexCount_ )
+      , pQueueFamilyIndices( pQueueFamilyIndices_ )
+      , initialLayout( initialLayout_ )
+    {
+    }
+
+    ImageCreateInfo( VkImageCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageCreateInfo) );
+    }
+
+    ImageCreateInfo& operator=( VkImageCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImageCreateInfo) );
+      return *this;
+    }
+
+    ImageCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ImageCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ImageCreateInfo& setFlags( ImageCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    ImageCreateInfo& setImageType( ImageType imageType_ )
+    {
+      imageType = imageType_;
+      return *this;
+    }
+
+    ImageCreateInfo& setFormat( Format format_ )
+    {
+      format = format_;
+      return *this;
+    }
+
+    ImageCreateInfo& setExtent( Extent3D extent_ )
+    {
+      extent = extent_;
+      return *this;
+    }
+
+    ImageCreateInfo& setMipLevels( uint32_t mipLevels_ )
+    {
+      mipLevels = mipLevels_;
+      return *this;
+    }
+
+    ImageCreateInfo& setArrayLayers( uint32_t arrayLayers_ )
+    {
+      arrayLayers = arrayLayers_;
+      return *this;
+    }
+
+    ImageCreateInfo& setSamples( SampleCountFlagBits samples_ )
+    {
+      samples = samples_;
+      return *this;
+    }
+
+    ImageCreateInfo& setTiling( ImageTiling tiling_ )
+    {
+      tiling = tiling_;
+      return *this;
+    }
+
+    ImageCreateInfo& setUsage( ImageUsageFlags usage_ )
+    {
+      usage = usage_;
+      return *this;
+    }
+
+    ImageCreateInfo& setSharingMode( SharingMode sharingMode_ )
+    {
+      sharingMode = sharingMode_;
+      return *this;
+    }
+
+    ImageCreateInfo& setQueueFamilyIndexCount( uint32_t queueFamilyIndexCount_ )
+    {
+      queueFamilyIndexCount = queueFamilyIndexCount_;
+      return *this;
+    }
+
+    ImageCreateInfo& setPQueueFamilyIndices( const uint32_t* pQueueFamilyIndices_ )
+    {
+      pQueueFamilyIndices = pQueueFamilyIndices_;
+      return *this;
+    }
+
+    ImageCreateInfo& setInitialLayout( ImageLayout initialLayout_ )
+    {
+      initialLayout = initialLayout_;
+      return *this;
+    }
+
+    operator const VkImageCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkImageCreateInfo*>(this);
+    }
+
+    bool operator==( ImageCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( imageType == rhs.imageType )
+          && ( format == rhs.format )
+          && ( extent == rhs.extent )
+          && ( mipLevels == rhs.mipLevels )
+          && ( arrayLayers == rhs.arrayLayers )
+          && ( samples == rhs.samples )
+          && ( tiling == rhs.tiling )
+          && ( usage == rhs.usage )
+          && ( sharingMode == rhs.sharingMode )
+          && ( queueFamilyIndexCount == rhs.queueFamilyIndexCount )
+          && ( pQueueFamilyIndices == rhs.pQueueFamilyIndices )
+          && ( initialLayout == rhs.initialLayout );
+    }
+
+    bool operator!=( ImageCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    ImageCreateFlags flags;
+    ImageType imageType;
+    Format format;
+    Extent3D extent;
+    uint32_t mipLevels;
+    uint32_t arrayLayers;
+    SampleCountFlagBits samples;
+    ImageTiling tiling;
+    ImageUsageFlags usage;
+    SharingMode sharingMode;
+    uint32_t queueFamilyIndexCount;
+    const uint32_t* pQueueFamilyIndices;
+    ImageLayout initialLayout;
+  };
+  static_assert( sizeof( ImageCreateInfo ) == sizeof( VkImageCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PipelineMultisampleStateCreateInfo
+  {
+    PipelineMultisampleStateCreateInfo( PipelineMultisampleStateCreateFlags flags_ = PipelineMultisampleStateCreateFlags(), SampleCountFlagBits rasterizationSamples_ = SampleCountFlagBits::e1, Bool32 sampleShadingEnable_ = 0, float minSampleShading_ = 0, const SampleMask* pSampleMask_ = nullptr, Bool32 alphaToCoverageEnable_ = 0, Bool32 alphaToOneEnable_ = 0 )
+      : sType( StructureType::ePipelineMultisampleStateCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , rasterizationSamples( rasterizationSamples_ )
+      , sampleShadingEnable( sampleShadingEnable_ )
+      , minSampleShading( minSampleShading_ )
+      , pSampleMask( pSampleMask_ )
+      , alphaToCoverageEnable( alphaToCoverageEnable_ )
+      , alphaToOneEnable( alphaToOneEnable_ )
+    {
+    }
+
+    PipelineMultisampleStateCreateInfo( VkPipelineMultisampleStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineMultisampleStateCreateInfo) );
+    }
+
+    PipelineMultisampleStateCreateInfo& operator=( VkPipelineMultisampleStateCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineMultisampleStateCreateInfo) );
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setFlags( PipelineMultisampleStateCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setRasterizationSamples( SampleCountFlagBits rasterizationSamples_ )
+    {
+      rasterizationSamples = rasterizationSamples_;
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setSampleShadingEnable( Bool32 sampleShadingEnable_ )
+    {
+      sampleShadingEnable = sampleShadingEnable_;
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setMinSampleShading( float minSampleShading_ )
+    {
+      minSampleShading = minSampleShading_;
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setPSampleMask( const SampleMask* pSampleMask_ )
+    {
+      pSampleMask = pSampleMask_;
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setAlphaToCoverageEnable( Bool32 alphaToCoverageEnable_ )
+    {
+      alphaToCoverageEnable = alphaToCoverageEnable_;
+      return *this;
+    }
+
+    PipelineMultisampleStateCreateInfo& setAlphaToOneEnable( Bool32 alphaToOneEnable_ )
+    {
+      alphaToOneEnable = alphaToOneEnable_;
+      return *this;
+    }
+
+    operator const VkPipelineMultisampleStateCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkPipelineMultisampleStateCreateInfo*>(this);
+    }
+
+    bool operator==( PipelineMultisampleStateCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( rasterizationSamples == rhs.rasterizationSamples )
+          && ( sampleShadingEnable == rhs.sampleShadingEnable )
+          && ( minSampleShading == rhs.minSampleShading )
+          && ( pSampleMask == rhs.pSampleMask )
+          && ( alphaToCoverageEnable == rhs.alphaToCoverageEnable )
+          && ( alphaToOneEnable == rhs.alphaToOneEnable );
+    }
+
+    bool operator!=( PipelineMultisampleStateCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineMultisampleStateCreateFlags flags;
+    SampleCountFlagBits rasterizationSamples;
+    Bool32 sampleShadingEnable;
+    float minSampleShading;
+    const SampleMask* pSampleMask;
+    Bool32 alphaToCoverageEnable;
+    Bool32 alphaToOneEnable;
+  };
+  static_assert( sizeof( PipelineMultisampleStateCreateInfo ) == sizeof( VkPipelineMultisampleStateCreateInfo ), "struct and wrapper have different size!" );
+
+  struct GraphicsPipelineCreateInfo
+  {
+    GraphicsPipelineCreateInfo( PipelineCreateFlags flags_ = PipelineCreateFlags(), uint32_t stageCount_ = 0, const PipelineShaderStageCreateInfo* pStages_ = nullptr, const PipelineVertexInputStateCreateInfo* pVertexInputState_ = nullptr, const PipelineInputAssemblyStateCreateInfo* pInputAssemblyState_ = nullptr, const PipelineTessellationStateCreateInfo* pTessellationState_ = nullptr, const PipelineViewportStateCreateInfo* pViewportState_ = nullptr, const PipelineRasterizationStateCreateInfo* pRasterizationState_ = nullptr, const PipelineMultisampleStateCreateInfo* pMultisampleState_ = nullptr, const PipelineDepthStencilStateCreateInfo* pDepthStencilState_ = nullptr, const PipelineColorBlendStateCreateInfo* pColorBlendState_ = nullptr, const PipelineDynamicStateCreateInfo* pDynamicState_ = nullptr, PipelineLayout layout_ = PipelineLayout(), RenderPass renderPass_ = RenderPass(), uint32_t subpass_ = 0, Pipeline basePipelineHandle_ = Pipeline(), int32_t basePipelineIndex_ = 0 )
+      : sType( StructureType::eGraphicsPipelineCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , stageCount( stageCount_ )
+      , pStages( pStages_ )
+      , pVertexInputState( pVertexInputState_ )
+      , pInputAssemblyState( pInputAssemblyState_ )
+      , pTessellationState( pTessellationState_ )
+      , pViewportState( pViewportState_ )
+      , pRasterizationState( pRasterizationState_ )
+      , pMultisampleState( pMultisampleState_ )
+      , pDepthStencilState( pDepthStencilState_ )
+      , pColorBlendState( pColorBlendState_ )
+      , pDynamicState( pDynamicState_ )
+      , layout( layout_ )
+      , renderPass( renderPass_ )
+      , subpass( subpass_ )
+      , basePipelineHandle( basePipelineHandle_ )
+      , basePipelineIndex( basePipelineIndex_ )
+    {
+    }
+
+    GraphicsPipelineCreateInfo( VkGraphicsPipelineCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(GraphicsPipelineCreateInfo) );
+    }
+
+    GraphicsPipelineCreateInfo& operator=( VkGraphicsPipelineCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(GraphicsPipelineCreateInfo) );
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setFlags( PipelineCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setStageCount( uint32_t stageCount_ )
+    {
+      stageCount = stageCount_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPStages( const PipelineShaderStageCreateInfo* pStages_ )
+    {
+      pStages = pStages_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPVertexInputState( const PipelineVertexInputStateCreateInfo* pVertexInputState_ )
+    {
+      pVertexInputState = pVertexInputState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPInputAssemblyState( const PipelineInputAssemblyStateCreateInfo* pInputAssemblyState_ )
+    {
+      pInputAssemblyState = pInputAssemblyState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPTessellationState( const PipelineTessellationStateCreateInfo* pTessellationState_ )
+    {
+      pTessellationState = pTessellationState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPViewportState( const PipelineViewportStateCreateInfo* pViewportState_ )
+    {
+      pViewportState = pViewportState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPRasterizationState( const PipelineRasterizationStateCreateInfo* pRasterizationState_ )
+    {
+      pRasterizationState = pRasterizationState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPMultisampleState( const PipelineMultisampleStateCreateInfo* pMultisampleState_ )
+    {
+      pMultisampleState = pMultisampleState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPDepthStencilState( const PipelineDepthStencilStateCreateInfo* pDepthStencilState_ )
+    {
+      pDepthStencilState = pDepthStencilState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPColorBlendState( const PipelineColorBlendStateCreateInfo* pColorBlendState_ )
+    {
+      pColorBlendState = pColorBlendState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setPDynamicState( const PipelineDynamicStateCreateInfo* pDynamicState_ )
+    {
+      pDynamicState = pDynamicState_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setLayout( PipelineLayout layout_ )
+    {
+      layout = layout_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setRenderPass( RenderPass renderPass_ )
+    {
+      renderPass = renderPass_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setSubpass( uint32_t subpass_ )
+    {
+      subpass = subpass_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setBasePipelineHandle( Pipeline basePipelineHandle_ )
+    {
+      basePipelineHandle = basePipelineHandle_;
+      return *this;
+    }
+
+    GraphicsPipelineCreateInfo& setBasePipelineIndex( int32_t basePipelineIndex_ )
+    {
+      basePipelineIndex = basePipelineIndex_;
+      return *this;
+    }
+
+    operator const VkGraphicsPipelineCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkGraphicsPipelineCreateInfo*>(this);
+    }
+
+    bool operator==( GraphicsPipelineCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( stageCount == rhs.stageCount )
+          && ( pStages == rhs.pStages )
+          && ( pVertexInputState == rhs.pVertexInputState )
+          && ( pInputAssemblyState == rhs.pInputAssemblyState )
+          && ( pTessellationState == rhs.pTessellationState )
+          && ( pViewportState == rhs.pViewportState )
+          && ( pRasterizationState == rhs.pRasterizationState )
+          && ( pMultisampleState == rhs.pMultisampleState )
+          && ( pDepthStencilState == rhs.pDepthStencilState )
+          && ( pColorBlendState == rhs.pColorBlendState )
+          && ( pDynamicState == rhs.pDynamicState )
+          && ( layout == rhs.layout )
+          && ( renderPass == rhs.renderPass )
+          && ( subpass == rhs.subpass )
+          && ( basePipelineHandle == rhs.basePipelineHandle )
+          && ( basePipelineIndex == rhs.basePipelineIndex );
+    }
+
+    bool operator!=( GraphicsPipelineCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    PipelineCreateFlags flags;
+    uint32_t stageCount;
+    const PipelineShaderStageCreateInfo* pStages;
+    const PipelineVertexInputStateCreateInfo* pVertexInputState;
+    const PipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+    const PipelineTessellationStateCreateInfo* pTessellationState;
+    const PipelineViewportStateCreateInfo* pViewportState;
+    const PipelineRasterizationStateCreateInfo* pRasterizationState;
+    const PipelineMultisampleStateCreateInfo* pMultisampleState;
+    const PipelineDepthStencilStateCreateInfo* pDepthStencilState;
+    const PipelineColorBlendStateCreateInfo* pColorBlendState;
+    const PipelineDynamicStateCreateInfo* pDynamicState;
+    PipelineLayout layout;
+    RenderPass renderPass;
+    uint32_t subpass;
+    Pipeline basePipelineHandle;
+    int32_t basePipelineIndex;
+  };
+  static_assert( sizeof( GraphicsPipelineCreateInfo ) == sizeof( VkGraphicsPipelineCreateInfo ), "struct and wrapper have different size!" );
+
+  struct PhysicalDeviceLimits
+  {
+    operator const VkPhysicalDeviceLimits&() const
+    {
+      return *reinterpret_cast<const VkPhysicalDeviceLimits*>(this);
+    }
+
+    bool operator==( PhysicalDeviceLimits const& rhs ) const
+    {
+      return ( maxImageDimension1D == rhs.maxImageDimension1D )
+          && ( maxImageDimension2D == rhs.maxImageDimension2D )
+          && ( maxImageDimension3D == rhs.maxImageDimension3D )
+          && ( maxImageDimensionCube == rhs.maxImageDimensionCube )
+          && ( maxImageArrayLayers == rhs.maxImageArrayLayers )
+          && ( maxTexelBufferElements == rhs.maxTexelBufferElements )
+          && ( maxUniformBufferRange == rhs.maxUniformBufferRange )
+          && ( maxStorageBufferRange == rhs.maxStorageBufferRange )
+          && ( maxPushConstantsSize == rhs.maxPushConstantsSize )
+          && ( maxMemoryAllocationCount == rhs.maxMemoryAllocationCount )
+          && ( maxSamplerAllocationCount == rhs.maxSamplerAllocationCount )
+          && ( bufferImageGranularity == rhs.bufferImageGranularity )
+          && ( sparseAddressSpaceSize == rhs.sparseAddressSpaceSize )
+          && ( maxBoundDescriptorSets == rhs.maxBoundDescriptorSets )
+          && ( maxPerStageDescriptorSamplers == rhs.maxPerStageDescriptorSamplers )
+          && ( maxPerStageDescriptorUniformBuffers == rhs.maxPerStageDescriptorUniformBuffers )
+          && ( maxPerStageDescriptorStorageBuffers == rhs.maxPerStageDescriptorStorageBuffers )
+          && ( maxPerStageDescriptorSampledImages == rhs.maxPerStageDescriptorSampledImages )
+          && ( maxPerStageDescriptorStorageImages == rhs.maxPerStageDescriptorStorageImages )
+          && ( maxPerStageDescriptorInputAttachments == rhs.maxPerStageDescriptorInputAttachments )
+          && ( maxPerStageResources == rhs.maxPerStageResources )
+          && ( maxDescriptorSetSamplers == rhs.maxDescriptorSetSamplers )
+          && ( maxDescriptorSetUniformBuffers == rhs.maxDescriptorSetUniformBuffers )
+          && ( maxDescriptorSetUniformBuffersDynamic == rhs.maxDescriptorSetUniformBuffersDynamic )
+          && ( maxDescriptorSetStorageBuffers == rhs.maxDescriptorSetStorageBuffers )
+          && ( maxDescriptorSetStorageBuffersDynamic == rhs.maxDescriptorSetStorageBuffersDynamic )
+          && ( maxDescriptorSetSampledImages == rhs.maxDescriptorSetSampledImages )
+          && ( maxDescriptorSetStorageImages == rhs.maxDescriptorSetStorageImages )
+          && ( maxDescriptorSetInputAttachments == rhs.maxDescriptorSetInputAttachments )
+          && ( maxVertexInputAttributes == rhs.maxVertexInputAttributes )
+          && ( maxVertexInputBindings == rhs.maxVertexInputBindings )
+          && ( maxVertexInputAttributeOffset == rhs.maxVertexInputAttributeOffset )
+          && ( maxVertexInputBindingStride == rhs.maxVertexInputBindingStride )
+          && ( maxVertexOutputComponents == rhs.maxVertexOutputComponents )
+          && ( maxTessellationGenerationLevel == rhs.maxTessellationGenerationLevel )
+          && ( maxTessellationPatchSize == rhs.maxTessellationPatchSize )
+          && ( maxTessellationControlPerVertexInputComponents == rhs.maxTessellationControlPerVertexInputComponents )
+          && ( maxTessellationControlPerVertexOutputComponents == rhs.maxTessellationControlPerVertexOutputComponents )
+          && ( maxTessellationControlPerPatchOutputComponents == rhs.maxTessellationControlPerPatchOutputComponents )
+          && ( maxTessellationControlTotalOutputComponents == rhs.maxTessellationControlTotalOutputComponents )
+          && ( maxTessellationEvaluationInputComponents == rhs.maxTessellationEvaluationInputComponents )
+          && ( maxTessellationEvaluationOutputComponents == rhs.maxTessellationEvaluationOutputComponents )
+          && ( maxGeometryShaderInvocations == rhs.maxGeometryShaderInvocations )
+          && ( maxGeometryInputComponents == rhs.maxGeometryInputComponents )
+          && ( maxGeometryOutputComponents == rhs.maxGeometryOutputComponents )
+          && ( maxGeometryOutputVertices == rhs.maxGeometryOutputVertices )
+          && ( maxGeometryTotalOutputComponents == rhs.maxGeometryTotalOutputComponents )
+          && ( maxFragmentInputComponents == rhs.maxFragmentInputComponents )
+          && ( maxFragmentOutputAttachments == rhs.maxFragmentOutputAttachments )
+          && ( maxFragmentDualSrcAttachments == rhs.maxFragmentDualSrcAttachments )
+          && ( maxFragmentCombinedOutputResources == rhs.maxFragmentCombinedOutputResources )
+          && ( maxComputeSharedMemorySize == rhs.maxComputeSharedMemorySize )
+          && ( memcmp( maxComputeWorkGroupCount, rhs.maxComputeWorkGroupCount, 3 * sizeof( uint32_t ) ) == 0 )
+          && ( maxComputeWorkGroupInvocations == rhs.maxComputeWorkGroupInvocations )
+          && ( memcmp( maxComputeWorkGroupSize, rhs.maxComputeWorkGroupSize, 3 * sizeof( uint32_t ) ) == 0 )
+          && ( subPixelPrecisionBits == rhs.subPixelPrecisionBits )
+          && ( subTexelPrecisionBits == rhs.subTexelPrecisionBits )
+          && ( mipmapPrecisionBits == rhs.mipmapPrecisionBits )
+          && ( maxDrawIndexedIndexValue == rhs.maxDrawIndexedIndexValue )
+          && ( maxDrawIndirectCount == rhs.maxDrawIndirectCount )
+          && ( maxSamplerLodBias == rhs.maxSamplerLodBias )
+          && ( maxSamplerAnisotropy == rhs.maxSamplerAnisotropy )
+          && ( maxViewports == rhs.maxViewports )
+          && ( memcmp( maxViewportDimensions, rhs.maxViewportDimensions, 2 * sizeof( uint32_t ) ) == 0 )
+          && ( memcmp( viewportBoundsRange, rhs.viewportBoundsRange, 2 * sizeof( float ) ) == 0 )
+          && ( viewportSubPixelBits == rhs.viewportSubPixelBits )
+          && ( minMemoryMapAlignment == rhs.minMemoryMapAlignment )
+          && ( minTexelBufferOffsetAlignment == rhs.minTexelBufferOffsetAlignment )
+          && ( minUniformBufferOffsetAlignment == rhs.minUniformBufferOffsetAlignment )
+          && ( minStorageBufferOffsetAlignment == rhs.minStorageBufferOffsetAlignment )
+          && ( minTexelOffset == rhs.minTexelOffset )
+          && ( maxTexelOffset == rhs.maxTexelOffset )
+          && ( minTexelGatherOffset == rhs.minTexelGatherOffset )
+          && ( maxTexelGatherOffset == rhs.maxTexelGatherOffset )
+          && ( minInterpolationOffset == rhs.minInterpolationOffset )
+          && ( maxInterpolationOffset == rhs.maxInterpolationOffset )
+          && ( subPixelInterpolationOffsetBits == rhs.subPixelInterpolationOffsetBits )
+          && ( maxFramebufferWidth == rhs.maxFramebufferWidth )
+          && ( maxFramebufferHeight == rhs.maxFramebufferHeight )
+          && ( maxFramebufferLayers == rhs.maxFramebufferLayers )
+          && ( framebufferColorSampleCounts == rhs.framebufferColorSampleCounts )
+          && ( framebufferDepthSampleCounts == rhs.framebufferDepthSampleCounts )
+          && ( framebufferStencilSampleCounts == rhs.framebufferStencilSampleCounts )
+          && ( framebufferNoAttachmentsSampleCounts == rhs.framebufferNoAttachmentsSampleCounts )
+          && ( maxColorAttachments == rhs.maxColorAttachments )
+          && ( sampledImageColorSampleCounts == rhs.sampledImageColorSampleCounts )
+          && ( sampledImageIntegerSampleCounts == rhs.sampledImageIntegerSampleCounts )
+          && ( sampledImageDepthSampleCounts == rhs.sampledImageDepthSampleCounts )
+          && ( sampledImageStencilSampleCounts == rhs.sampledImageStencilSampleCounts )
+          && ( storageImageSampleCounts == rhs.storageImageSampleCounts )
+          && ( maxSampleMaskWords == rhs.maxSampleMaskWords )
+          && ( timestampComputeAndGraphics == rhs.timestampComputeAndGraphics )
+          && ( timestampPeriod == rhs.timestampPeriod )
+          && ( maxClipDistances == rhs.maxClipDistances )
+          && ( maxCullDistances == rhs.maxCullDistances )
+          && ( maxCombinedClipAndCullDistances == rhs.maxCombinedClipAndCullDistances )
+          && ( discreteQueuePriorities == rhs.discreteQueuePriorities )
+          && ( memcmp( pointSizeRange, rhs.pointSizeRange, 2 * sizeof( float ) ) == 0 )
+          && ( memcmp( lineWidthRange, rhs.lineWidthRange, 2 * sizeof( float ) ) == 0 )
+          && ( pointSizeGranularity == rhs.pointSizeGranularity )
+          && ( lineWidthGranularity == rhs.lineWidthGranularity )
+          && ( strictLines == rhs.strictLines )
+          && ( standardSampleLocations == rhs.standardSampleLocations )
+          && ( optimalBufferCopyOffsetAlignment == rhs.optimalBufferCopyOffsetAlignment )
+          && ( optimalBufferCopyRowPitchAlignment == rhs.optimalBufferCopyRowPitchAlignment )
+          && ( nonCoherentAtomSize == rhs.nonCoherentAtomSize );
+    }
+
+    bool operator!=( PhysicalDeviceLimits const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t maxImageDimension1D;
+    uint32_t maxImageDimension2D;
+    uint32_t maxImageDimension3D;
+    uint32_t maxImageDimensionCube;
+    uint32_t maxImageArrayLayers;
+    uint32_t maxTexelBufferElements;
+    uint32_t maxUniformBufferRange;
+    uint32_t maxStorageBufferRange;
+    uint32_t maxPushConstantsSize;
+    uint32_t maxMemoryAllocationCount;
+    uint32_t maxSamplerAllocationCount;
+    DeviceSize bufferImageGranularity;
+    DeviceSize sparseAddressSpaceSize;
+    uint32_t maxBoundDescriptorSets;
+    uint32_t maxPerStageDescriptorSamplers;
+    uint32_t maxPerStageDescriptorUniformBuffers;
+    uint32_t maxPerStageDescriptorStorageBuffers;
+    uint32_t maxPerStageDescriptorSampledImages;
+    uint32_t maxPerStageDescriptorStorageImages;
+    uint32_t maxPerStageDescriptorInputAttachments;
+    uint32_t maxPerStageResources;
+    uint32_t maxDescriptorSetSamplers;
+    uint32_t maxDescriptorSetUniformBuffers;
+    uint32_t maxDescriptorSetUniformBuffersDynamic;
+    uint32_t maxDescriptorSetStorageBuffers;
+    uint32_t maxDescriptorSetStorageBuffersDynamic;
+    uint32_t maxDescriptorSetSampledImages;
+    uint32_t maxDescriptorSetStorageImages;
+    uint32_t maxDescriptorSetInputAttachments;
+    uint32_t maxVertexInputAttributes;
+    uint32_t maxVertexInputBindings;
+    uint32_t maxVertexInputAttributeOffset;
+    uint32_t maxVertexInputBindingStride;
+    uint32_t maxVertexOutputComponents;
+    uint32_t maxTessellationGenerationLevel;
+    uint32_t maxTessellationPatchSize;
+    uint32_t maxTessellationControlPerVertexInputComponents;
+    uint32_t maxTessellationControlPerVertexOutputComponents;
+    uint32_t maxTessellationControlPerPatchOutputComponents;
+    uint32_t maxTessellationControlTotalOutputComponents;
+    uint32_t maxTessellationEvaluationInputComponents;
+    uint32_t maxTessellationEvaluationOutputComponents;
+    uint32_t maxGeometryShaderInvocations;
+    uint32_t maxGeometryInputComponents;
+    uint32_t maxGeometryOutputComponents;
+    uint32_t maxGeometryOutputVertices;
+    uint32_t maxGeometryTotalOutputComponents;
+    uint32_t maxFragmentInputComponents;
+    uint32_t maxFragmentOutputAttachments;
+    uint32_t maxFragmentDualSrcAttachments;
+    uint32_t maxFragmentCombinedOutputResources;
+    uint32_t maxComputeSharedMemorySize;
+    uint32_t maxComputeWorkGroupCount[3];
+    uint32_t maxComputeWorkGroupInvocations;
+    uint32_t maxComputeWorkGroupSize[3];
+    uint32_t subPixelPrecisionBits;
+    uint32_t subTexelPrecisionBits;
+    uint32_t mipmapPrecisionBits;
+    uint32_t maxDrawIndexedIndexValue;
+    uint32_t maxDrawIndirectCount;
+    float maxSamplerLodBias;
+    float maxSamplerAnisotropy;
+    uint32_t maxViewports;
+    uint32_t maxViewportDimensions[2];
+    float viewportBoundsRange[2];
+    uint32_t viewportSubPixelBits;
+    size_t minMemoryMapAlignment;
+    DeviceSize minTexelBufferOffsetAlignment;
+    DeviceSize minUniformBufferOffsetAlignment;
+    DeviceSize minStorageBufferOffsetAlignment;
+    int32_t minTexelOffset;
+    uint32_t maxTexelOffset;
+    int32_t minTexelGatherOffset;
+    uint32_t maxTexelGatherOffset;
+    float minInterpolationOffset;
+    float maxInterpolationOffset;
+    uint32_t subPixelInterpolationOffsetBits;
+    uint32_t maxFramebufferWidth;
+    uint32_t maxFramebufferHeight;
+    uint32_t maxFramebufferLayers;
+    SampleCountFlags framebufferColorSampleCounts;
+    SampleCountFlags framebufferDepthSampleCounts;
+    SampleCountFlags framebufferStencilSampleCounts;
+    SampleCountFlags framebufferNoAttachmentsSampleCounts;
+    uint32_t maxColorAttachments;
+    SampleCountFlags sampledImageColorSampleCounts;
+    SampleCountFlags sampledImageIntegerSampleCounts;
+    SampleCountFlags sampledImageDepthSampleCounts;
+    SampleCountFlags sampledImageStencilSampleCounts;
+    SampleCountFlags storageImageSampleCounts;
+    uint32_t maxSampleMaskWords;
+    Bool32 timestampComputeAndGraphics;
+    float timestampPeriod;
+    uint32_t maxClipDistances;
+    uint32_t maxCullDistances;
+    uint32_t maxCombinedClipAndCullDistances;
+    uint32_t discreteQueuePriorities;
+    float pointSizeRange[2];
+    float lineWidthRange[2];
+    float pointSizeGranularity;
+    float lineWidthGranularity;
+    Bool32 strictLines;
+    Bool32 standardSampleLocations;
+    DeviceSize optimalBufferCopyOffsetAlignment;
+    DeviceSize optimalBufferCopyRowPitchAlignment;
+    DeviceSize nonCoherentAtomSize;
+  };
+  static_assert( sizeof( PhysicalDeviceLimits ) == sizeof( VkPhysicalDeviceLimits ), "struct and wrapper have different size!" );
+
+  struct PhysicalDeviceProperties
+  {
+    operator const VkPhysicalDeviceProperties&() const
+    {
+      return *reinterpret_cast<const VkPhysicalDeviceProperties*>(this);
+    }
+
+    bool operator==( PhysicalDeviceProperties const& rhs ) const
+    {
+      return ( apiVersion == rhs.apiVersion )
+          && ( driverVersion == rhs.driverVersion )
+          && ( vendorID == rhs.vendorID )
+          && ( deviceID == rhs.deviceID )
+          && ( deviceType == rhs.deviceType )
+          && ( memcmp( deviceName, rhs.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE * sizeof( char ) ) == 0 )
+          && ( memcmp( pipelineCacheUUID, rhs.pipelineCacheUUID, VK_UUID_SIZE * sizeof( uint8_t ) ) == 0 )
+          && ( limits == rhs.limits )
+          && ( sparseProperties == rhs.sparseProperties );
+    }
+
+    bool operator!=( PhysicalDeviceProperties const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t apiVersion;
+    uint32_t driverVersion;
+    uint32_t vendorID;
+    uint32_t deviceID;
+    PhysicalDeviceType deviceType;
+    char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
+    uint8_t pipelineCacheUUID[VK_UUID_SIZE];
+    PhysicalDeviceLimits limits;
+    PhysicalDeviceSparseProperties sparseProperties;
+  };
+  static_assert( sizeof( PhysicalDeviceProperties ) == sizeof( VkPhysicalDeviceProperties ), "struct and wrapper have different size!" );
+
+  enum class AttachmentDescriptionFlagBits
+  {
+    eMayAlias = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
+  };
+
+  using AttachmentDescriptionFlags = Flags<AttachmentDescriptionFlagBits, VkAttachmentDescriptionFlags>;
+
+  inline AttachmentDescriptionFlags operator|( AttachmentDescriptionFlagBits bit0, AttachmentDescriptionFlagBits bit1 )
+  {
+    return AttachmentDescriptionFlags( bit0 ) | bit1;
+  }
+
+  struct AttachmentDescription
+  {
+    AttachmentDescription( AttachmentDescriptionFlags flags_ = AttachmentDescriptionFlags(), Format format_ = Format::eUndefined, SampleCountFlagBits samples_ = SampleCountFlagBits::e1, AttachmentLoadOp loadOp_ = AttachmentLoadOp::eLoad, AttachmentStoreOp storeOp_ = AttachmentStoreOp::eStore, AttachmentLoadOp stencilLoadOp_ = AttachmentLoadOp::eLoad, AttachmentStoreOp stencilStoreOp_ = AttachmentStoreOp::eStore, ImageLayout initialLayout_ = ImageLayout::eUndefined, ImageLayout finalLayout_ = ImageLayout::eUndefined )
+      : flags( flags_ )
+      , format( format_ )
+      , samples( samples_ )
+      , loadOp( loadOp_ )
+      , storeOp( storeOp_ )
+      , stencilLoadOp( stencilLoadOp_ )
+      , stencilStoreOp( stencilStoreOp_ )
+      , initialLayout( initialLayout_ )
+      , finalLayout( finalLayout_ )
+    {
+    }
+
+    AttachmentDescription( VkAttachmentDescription const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(AttachmentDescription) );
+    }
+
+    AttachmentDescription& operator=( VkAttachmentDescription const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(AttachmentDescription) );
+      return *this;
+    }
+
+    AttachmentDescription& setFlags( AttachmentDescriptionFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    AttachmentDescription& setFormat( Format format_ )
+    {
+      format = format_;
+      return *this;
+    }
+
+    AttachmentDescription& setSamples( SampleCountFlagBits samples_ )
+    {
+      samples = samples_;
+      return *this;
+    }
+
+    AttachmentDescription& setLoadOp( AttachmentLoadOp loadOp_ )
+    {
+      loadOp = loadOp_;
+      return *this;
+    }
+
+    AttachmentDescription& setStoreOp( AttachmentStoreOp storeOp_ )
+    {
+      storeOp = storeOp_;
+      return *this;
+    }
+
+    AttachmentDescription& setStencilLoadOp( AttachmentLoadOp stencilLoadOp_ )
+    {
+      stencilLoadOp = stencilLoadOp_;
+      return *this;
+    }
+
+    AttachmentDescription& setStencilStoreOp( AttachmentStoreOp stencilStoreOp_ )
+    {
+      stencilStoreOp = stencilStoreOp_;
+      return *this;
+    }
+
+    AttachmentDescription& setInitialLayout( ImageLayout initialLayout_ )
+    {
+      initialLayout = initialLayout_;
+      return *this;
+    }
+
+    AttachmentDescription& setFinalLayout( ImageLayout finalLayout_ )
+    {
+      finalLayout = finalLayout_;
+      return *this;
+    }
+
+    operator const VkAttachmentDescription&() const
+    {
+      return *reinterpret_cast<const VkAttachmentDescription*>(this);
+    }
+
+    bool operator==( AttachmentDescription const& rhs ) const
+    {
+      return ( flags == rhs.flags )
+          && ( format == rhs.format )
+          && ( samples == rhs.samples )
+          && ( loadOp == rhs.loadOp )
+          && ( storeOp == rhs.storeOp )
+          && ( stencilLoadOp == rhs.stencilLoadOp )
+          && ( stencilStoreOp == rhs.stencilStoreOp )
+          && ( initialLayout == rhs.initialLayout )
+          && ( finalLayout == rhs.finalLayout );
+    }
+
+    bool operator!=( AttachmentDescription const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    AttachmentDescriptionFlags flags;
+    Format format;
+    SampleCountFlagBits samples;
+    AttachmentLoadOp loadOp;
+    AttachmentStoreOp storeOp;
+    AttachmentLoadOp stencilLoadOp;
+    AttachmentStoreOp stencilStoreOp;
+    ImageLayout initialLayout;
+    ImageLayout finalLayout;
+  };
+  static_assert( sizeof( AttachmentDescription ) == sizeof( VkAttachmentDescription ), "struct and wrapper have different size!" );
+
+  enum class StencilFaceFlagBits
+  {
+    eFront = VK_STENCIL_FACE_FRONT_BIT,
+    eBack = VK_STENCIL_FACE_BACK_BIT,
+    eVkStencilFrontAndBack = VK_STENCIL_FRONT_AND_BACK
+  };
+
+  using StencilFaceFlags = Flags<StencilFaceFlagBits, VkStencilFaceFlags>;
+
+  inline StencilFaceFlags operator|( StencilFaceFlagBits bit0, StencilFaceFlagBits bit1 )
+  {
+    return StencilFaceFlags( bit0 ) | bit1;
+  }
+
+  enum class DescriptorPoolCreateFlagBits
+  {
+    eFreeDescriptorSet = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT
+  };
+
+  using DescriptorPoolCreateFlags = Flags<DescriptorPoolCreateFlagBits, VkDescriptorPoolCreateFlags>;
+
+  inline DescriptorPoolCreateFlags operator|( DescriptorPoolCreateFlagBits bit0, DescriptorPoolCreateFlagBits bit1 )
+  {
+    return DescriptorPoolCreateFlags( bit0 ) | bit1;
+  }
+
+  struct DescriptorPoolCreateInfo
+  {
+    DescriptorPoolCreateInfo( DescriptorPoolCreateFlags flags_ = DescriptorPoolCreateFlags(), uint32_t maxSets_ = 0, uint32_t poolSizeCount_ = 0, const DescriptorPoolSize* pPoolSizes_ = nullptr )
+      : sType( StructureType::eDescriptorPoolCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , maxSets( maxSets_ )
+      , poolSizeCount( poolSizeCount_ )
+      , pPoolSizes( pPoolSizes_ )
+    {
+    }
+
+    DescriptorPoolCreateInfo( VkDescriptorPoolCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorPoolCreateInfo) );
+    }
+
+    DescriptorPoolCreateInfo& operator=( VkDescriptorPoolCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DescriptorPoolCreateInfo) );
+      return *this;
+    }
+
+    DescriptorPoolCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DescriptorPoolCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DescriptorPoolCreateInfo& setFlags( DescriptorPoolCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    DescriptorPoolCreateInfo& setMaxSets( uint32_t maxSets_ )
+    {
+      maxSets = maxSets_;
+      return *this;
+    }
+
+    DescriptorPoolCreateInfo& setPoolSizeCount( uint32_t poolSizeCount_ )
+    {
+      poolSizeCount = poolSizeCount_;
+      return *this;
+    }
+
+    DescriptorPoolCreateInfo& setPPoolSizes( const DescriptorPoolSize* pPoolSizes_ )
+    {
+      pPoolSizes = pPoolSizes_;
+      return *this;
+    }
+
+    operator const VkDescriptorPoolCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkDescriptorPoolCreateInfo*>(this);
+    }
+
+    bool operator==( DescriptorPoolCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( maxSets == rhs.maxSets )
+          && ( poolSizeCount == rhs.poolSizeCount )
+          && ( pPoolSizes == rhs.pPoolSizes );
+    }
+
+    bool operator!=( DescriptorPoolCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DescriptorPoolCreateFlags flags;
+    uint32_t maxSets;
+    uint32_t poolSizeCount;
+    const DescriptorPoolSize* pPoolSizes;
+  };
+  static_assert( sizeof( DescriptorPoolCreateInfo ) == sizeof( VkDescriptorPoolCreateInfo ), "struct and wrapper have different size!" );
+
+  enum class DependencyFlagBits
+  {
+    eByRegion = VK_DEPENDENCY_BY_REGION_BIT
+  };
+
+  using DependencyFlags = Flags<DependencyFlagBits, VkDependencyFlags>;
+
+  inline DependencyFlags operator|( DependencyFlagBits bit0, DependencyFlagBits bit1 )
+  {
+    return DependencyFlags( bit0 ) | bit1;
+  }
+
+  class CommandBuffer
+  {
+  public:
+    CommandBuffer()
+      : m_commandBuffer(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    CommandBuffer(VkCommandBuffer commandBuffer)
+       : m_commandBuffer(commandBuffer)
+    {}
+
+    CommandBuffer& operator=(VkCommandBuffer commandBuffer)
+    {
+      m_commandBuffer = commandBuffer;
+      return *this;
+    }
+#endif
+
+    Result begin( const CommandBufferBeginInfo* pBeginInfo ) const
+    {
+      return static_cast<Result>( vkBeginCommandBuffer( m_commandBuffer, reinterpret_cast<const VkCommandBufferBeginInfo*>( pBeginInfo ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type begin( const CommandBufferBeginInfo & beginInfo ) const
+    {
+      Result result = static_cast<Result>( vkBeginCommandBuffer( m_commandBuffer, reinterpret_cast<const VkCommandBufferBeginInfo*>( &beginInfo ) ) );
+      return createResultValue( result, "vk::CommandBuffer::begin" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result end(  ) const
+    {
+      return static_cast<Result>( vkEndCommandBuffer( m_commandBuffer ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type end() const
+    {
+      Result result = static_cast<Result>( vkEndCommandBuffer( m_commandBuffer ) );
+      return createResultValue( result, "vk::CommandBuffer::end" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result reset( CommandBufferResetFlags flags ) const
+    {
+      return static_cast<Result>( vkResetCommandBuffer( m_commandBuffer, static_cast<VkCommandBufferResetFlags>( flags ) ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type reset( CommandBufferResetFlags flags ) const
+    {
+      Result result = static_cast<Result>( vkResetCommandBuffer( m_commandBuffer, static_cast<VkCommandBufferResetFlags>( flags ) ) );
+      return createResultValue( result, "vk::CommandBuffer::reset" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void bindPipeline( PipelineBindPoint pipelineBindPoint, Pipeline pipeline ) const
+    {
+      vkCmdBindPipeline( m_commandBuffer, static_cast<VkPipelineBindPoint>( pipelineBindPoint ), static_cast<VkPipeline>( pipeline ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void bindPipeline( PipelineBindPoint pipelineBindPoint, Pipeline pipeline ) const
+    {
+      vkCmdBindPipeline( m_commandBuffer, static_cast<VkPipelineBindPoint>( pipelineBindPoint ), static_cast<VkPipeline>( pipeline ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void setViewport( uint32_t firstViewport, uint32_t viewportCount, const Viewport* pViewports ) const
+    {
+      vkCmdSetViewport( m_commandBuffer, firstViewport, viewportCount, reinterpret_cast<const VkViewport*>( pViewports ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setViewport( uint32_t firstViewport, ArrayProxy<const Viewport> viewports ) const
+    {
+      vkCmdSetViewport( m_commandBuffer, firstViewport, viewports.size() , reinterpret_cast<const VkViewport*>( viewports.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void setScissor( uint32_t firstScissor, uint32_t scissorCount, const Rect2D* pScissors ) const
+    {
+      vkCmdSetScissor( m_commandBuffer, firstScissor, scissorCount, reinterpret_cast<const VkRect2D*>( pScissors ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setScissor( uint32_t firstScissor, ArrayProxy<const Rect2D> scissors ) const
+    {
+      vkCmdSetScissor( m_commandBuffer, firstScissor, scissors.size() , reinterpret_cast<const VkRect2D*>( scissors.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setLineWidth( float lineWidth ) const
+    {
+      vkCmdSetLineWidth( m_commandBuffer, lineWidth );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setLineWidth( float lineWidth ) const
+    {
+      vkCmdSetLineWidth( m_commandBuffer, lineWidth );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setDepthBias( float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor ) const
+    {
+      vkCmdSetDepthBias( m_commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setDepthBias( float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor ) const
+    {
+      vkCmdSetDepthBias( m_commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setBlendConstants( const float blendConstants[4] ) const
+    {
+      vkCmdSetBlendConstants( m_commandBuffer, blendConstants );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setBlendConstants( const float blendConstants[4] ) const
+    {
+      vkCmdSetBlendConstants( m_commandBuffer, blendConstants );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setDepthBounds( float minDepthBounds, float maxDepthBounds ) const
+    {
+      vkCmdSetDepthBounds( m_commandBuffer, minDepthBounds, maxDepthBounds );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setDepthBounds( float minDepthBounds, float maxDepthBounds ) const
+    {
+      vkCmdSetDepthBounds( m_commandBuffer, minDepthBounds, maxDepthBounds );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setStencilCompareMask( StencilFaceFlags faceMask, uint32_t compareMask ) const
+    {
+      vkCmdSetStencilCompareMask( m_commandBuffer, static_cast<VkStencilFaceFlags>( faceMask ), compareMask );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setStencilCompareMask( StencilFaceFlags faceMask, uint32_t compareMask ) const
+    {
+      vkCmdSetStencilCompareMask( m_commandBuffer, static_cast<VkStencilFaceFlags>( faceMask ), compareMask );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setStencilWriteMask( StencilFaceFlags faceMask, uint32_t writeMask ) const
+    {
+      vkCmdSetStencilWriteMask( m_commandBuffer, static_cast<VkStencilFaceFlags>( faceMask ), writeMask );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setStencilWriteMask( StencilFaceFlags faceMask, uint32_t writeMask ) const
+    {
+      vkCmdSetStencilWriteMask( m_commandBuffer, static_cast<VkStencilFaceFlags>( faceMask ), writeMask );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setStencilReference( StencilFaceFlags faceMask, uint32_t reference ) const
+    {
+      vkCmdSetStencilReference( m_commandBuffer, static_cast<VkStencilFaceFlags>( faceMask ), reference );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setStencilReference( StencilFaceFlags faceMask, uint32_t reference ) const
+    {
+      vkCmdSetStencilReference( m_commandBuffer, static_cast<VkStencilFaceFlags>( faceMask ), reference );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void bindDescriptorSets( PipelineBindPoint pipelineBindPoint, PipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const DescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets ) const
+    {
+      vkCmdBindDescriptorSets( m_commandBuffer, static_cast<VkPipelineBindPoint>( pipelineBindPoint ), static_cast<VkPipelineLayout>( layout ), firstSet, descriptorSetCount, reinterpret_cast<const VkDescriptorSet*>( pDescriptorSets ), dynamicOffsetCount, pDynamicOffsets );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void bindDescriptorSets( PipelineBindPoint pipelineBindPoint, PipelineLayout layout, uint32_t firstSet, ArrayProxy<const DescriptorSet> descriptorSets, ArrayProxy<const uint32_t> dynamicOffsets ) const
+    {
+      vkCmdBindDescriptorSets( m_commandBuffer, static_cast<VkPipelineBindPoint>( pipelineBindPoint ), static_cast<VkPipelineLayout>( layout ), firstSet, descriptorSets.size() , reinterpret_cast<const VkDescriptorSet*>( descriptorSets.data() ), dynamicOffsets.size() , dynamicOffsets.data() );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void bindIndexBuffer( Buffer buffer, DeviceSize offset, IndexType indexType ) const
+    {
+      vkCmdBindIndexBuffer( m_commandBuffer, static_cast<VkBuffer>( buffer ), offset, static_cast<VkIndexType>( indexType ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void bindIndexBuffer( Buffer buffer, DeviceSize offset, IndexType indexType ) const
+    {
+      vkCmdBindIndexBuffer( m_commandBuffer, static_cast<VkBuffer>( buffer ), offset, static_cast<VkIndexType>( indexType ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void bindVertexBuffers( uint32_t firstBinding, uint32_t bindingCount, const Buffer* pBuffers, const DeviceSize* pOffsets ) const
+    {
+      vkCmdBindVertexBuffers( m_commandBuffer, firstBinding, bindingCount, reinterpret_cast<const VkBuffer*>( pBuffers ), pOffsets );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void bindVertexBuffers( uint32_t firstBinding, ArrayProxy<const Buffer> buffers, ArrayProxy<const DeviceSize> offsets ) const
+    {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+      assert( buffers.size() == offsets.size() );
+#else
+      if ( buffers.size() != offsets.size() )
+      {
+        throw std::logic_error( "vk::CommandBuffer::bindVertexBuffers: buffers.size() != offsets.size()" );
+      }
+#endif  // VULKAN_HPP_NO_EXCEPTIONS
+      vkCmdBindVertexBuffers( m_commandBuffer, firstBinding, buffers.size() , reinterpret_cast<const VkBuffer*>( buffers.data() ), offsets.data() );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void draw( uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance ) const
+    {
+      vkCmdDraw( m_commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void draw( uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance ) const
+    {
+      vkCmdDraw( m_commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void drawIndexed( uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance ) const
+    {
+      vkCmdDrawIndexed( m_commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void drawIndexed( uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance ) const
+    {
+      vkCmdDrawIndexed( m_commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void drawIndirect( Buffer buffer, DeviceSize offset, uint32_t drawCount, uint32_t stride ) const
+    {
+      vkCmdDrawIndirect( m_commandBuffer, static_cast<VkBuffer>( buffer ), offset, drawCount, stride );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void drawIndirect( Buffer buffer, DeviceSize offset, uint32_t drawCount, uint32_t stride ) const
+    {
+      vkCmdDrawIndirect( m_commandBuffer, static_cast<VkBuffer>( buffer ), offset, drawCount, stride );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void drawIndexedIndirect( Buffer buffer, DeviceSize offset, uint32_t drawCount, uint32_t stride ) const
+    {
+      vkCmdDrawIndexedIndirect( m_commandBuffer, static_cast<VkBuffer>( buffer ), offset, drawCount, stride );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void drawIndexedIndirect( Buffer buffer, DeviceSize offset, uint32_t drawCount, uint32_t stride ) const
+    {
+      vkCmdDrawIndexedIndirect( m_commandBuffer, static_cast<VkBuffer>( buffer ), offset, drawCount, stride );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void dispatch( uint32_t x, uint32_t y, uint32_t z ) const
+    {
+      vkCmdDispatch( m_commandBuffer, x, y, z );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void dispatch( uint32_t x, uint32_t y, uint32_t z ) const
+    {
+      vkCmdDispatch( m_commandBuffer, x, y, z );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void dispatchIndirect( Buffer buffer, DeviceSize offset ) const
+    {
+      vkCmdDispatchIndirect( m_commandBuffer, static_cast<VkBuffer>( buffer ), offset );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void dispatchIndirect( Buffer buffer, DeviceSize offset ) const
+    {
+      vkCmdDispatchIndirect( m_commandBuffer, static_cast<VkBuffer>( buffer ), offset );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void copyBuffer( Buffer srcBuffer, Buffer dstBuffer, uint32_t regionCount, const BufferCopy* pRegions ) const
+    {
+      vkCmdCopyBuffer( m_commandBuffer, static_cast<VkBuffer>( srcBuffer ), static_cast<VkBuffer>( dstBuffer ), regionCount, reinterpret_cast<const VkBufferCopy*>( pRegions ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void copyBuffer( Buffer srcBuffer, Buffer dstBuffer, ArrayProxy<const BufferCopy> regions ) const
+    {
+      vkCmdCopyBuffer( m_commandBuffer, static_cast<VkBuffer>( srcBuffer ), static_cast<VkBuffer>( dstBuffer ), regions.size() , reinterpret_cast<const VkBufferCopy*>( regions.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void copyImage( Image srcImage, ImageLayout srcImageLayout, Image dstImage, ImageLayout dstImageLayout, uint32_t regionCount, const ImageCopy* pRegions ) const
+    {
+      vkCmdCopyImage( m_commandBuffer, static_cast<VkImage>( srcImage ), static_cast<VkImageLayout>( srcImageLayout ), static_cast<VkImage>( dstImage ), static_cast<VkImageLayout>( dstImageLayout ), regionCount, reinterpret_cast<const VkImageCopy*>( pRegions ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void copyImage( Image srcImage, ImageLayout srcImageLayout, Image dstImage, ImageLayout dstImageLayout, ArrayProxy<const ImageCopy> regions ) const
+    {
+      vkCmdCopyImage( m_commandBuffer, static_cast<VkImage>( srcImage ), static_cast<VkImageLayout>( srcImageLayout ), static_cast<VkImage>( dstImage ), static_cast<VkImageLayout>( dstImageLayout ), regions.size() , reinterpret_cast<const VkImageCopy*>( regions.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void blitImage( Image srcImage, ImageLayout srcImageLayout, Image dstImage, ImageLayout dstImageLayout, uint32_t regionCount, const ImageBlit* pRegions, Filter filter ) const
+    {
+      vkCmdBlitImage( m_commandBuffer, static_cast<VkImage>( srcImage ), static_cast<VkImageLayout>( srcImageLayout ), static_cast<VkImage>( dstImage ), static_cast<VkImageLayout>( dstImageLayout ), regionCount, reinterpret_cast<const VkImageBlit*>( pRegions ), static_cast<VkFilter>( filter ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void blitImage( Image srcImage, ImageLayout srcImageLayout, Image dstImage, ImageLayout dstImageLayout, ArrayProxy<const ImageBlit> regions, Filter filter ) const
+    {
+      vkCmdBlitImage( m_commandBuffer, static_cast<VkImage>( srcImage ), static_cast<VkImageLayout>( srcImageLayout ), static_cast<VkImage>( dstImage ), static_cast<VkImageLayout>( dstImageLayout ), regions.size() , reinterpret_cast<const VkImageBlit*>( regions.data() ), static_cast<VkFilter>( filter ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void copyBufferToImage( Buffer srcBuffer, Image dstImage, ImageLayout dstImageLayout, uint32_t regionCount, const BufferImageCopy* pRegions ) const
+    {
+      vkCmdCopyBufferToImage( m_commandBuffer, static_cast<VkBuffer>( srcBuffer ), static_cast<VkImage>( dstImage ), static_cast<VkImageLayout>( dstImageLayout ), regionCount, reinterpret_cast<const VkBufferImageCopy*>( pRegions ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void copyBufferToImage( Buffer srcBuffer, Image dstImage, ImageLayout dstImageLayout, ArrayProxy<const BufferImageCopy> regions ) const
+    {
+      vkCmdCopyBufferToImage( m_commandBuffer, static_cast<VkBuffer>( srcBuffer ), static_cast<VkImage>( dstImage ), static_cast<VkImageLayout>( dstImageLayout ), regions.size() , reinterpret_cast<const VkBufferImageCopy*>( regions.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void copyImageToBuffer( Image srcImage, ImageLayout srcImageLayout, Buffer dstBuffer, uint32_t regionCount, const BufferImageCopy* pRegions ) const
+    {
+      vkCmdCopyImageToBuffer( m_commandBuffer, static_cast<VkImage>( srcImage ), static_cast<VkImageLayout>( srcImageLayout ), static_cast<VkBuffer>( dstBuffer ), regionCount, reinterpret_cast<const VkBufferImageCopy*>( pRegions ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void copyImageToBuffer( Image srcImage, ImageLayout srcImageLayout, Buffer dstBuffer, ArrayProxy<const BufferImageCopy> regions ) const
+    {
+      vkCmdCopyImageToBuffer( m_commandBuffer, static_cast<VkImage>( srcImage ), static_cast<VkImageLayout>( srcImageLayout ), static_cast<VkBuffer>( dstBuffer ), regions.size() , reinterpret_cast<const VkBufferImageCopy*>( regions.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void updateBuffer( Buffer dstBuffer, DeviceSize dstOffset, DeviceSize dataSize, const void* pData ) const
+    {
+      vkCmdUpdateBuffer( m_commandBuffer, static_cast<VkBuffer>( dstBuffer ), dstOffset, dataSize, pData );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename T>
+    void updateBuffer( Buffer dstBuffer, DeviceSize dstOffset, ArrayProxy<const T> data ) const
+    {
+      vkCmdUpdateBuffer( m_commandBuffer, static_cast<VkBuffer>( dstBuffer ), dstOffset, data.size() * sizeof( T ) , reinterpret_cast<const void*>( data.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void fillBuffer( Buffer dstBuffer, DeviceSize dstOffset, DeviceSize size, uint32_t data ) const
+    {
+      vkCmdFillBuffer( m_commandBuffer, static_cast<VkBuffer>( dstBuffer ), dstOffset, size, data );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void fillBuffer( Buffer dstBuffer, DeviceSize dstOffset, DeviceSize size, uint32_t data ) const
+    {
+      vkCmdFillBuffer( m_commandBuffer, static_cast<VkBuffer>( dstBuffer ), dstOffset, size, data );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void clearColorImage( Image image, ImageLayout imageLayout, const ClearColorValue* pColor, uint32_t rangeCount, const ImageSubresourceRange* pRanges ) const
+    {
+      vkCmdClearColorImage( m_commandBuffer, static_cast<VkImage>( image ), static_cast<VkImageLayout>( imageLayout ), reinterpret_cast<const VkClearColorValue*>( pColor ), rangeCount, reinterpret_cast<const VkImageSubresourceRange*>( pRanges ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void clearColorImage( Image image, ImageLayout imageLayout, const ClearColorValue & color, ArrayProxy<const ImageSubresourceRange> ranges ) const
+    {
+      vkCmdClearColorImage( m_commandBuffer, static_cast<VkImage>( image ), static_cast<VkImageLayout>( imageLayout ), reinterpret_cast<const VkClearColorValue*>( &color ), ranges.size() , reinterpret_cast<const VkImageSubresourceRange*>( ranges.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void clearDepthStencilImage( Image image, ImageLayout imageLayout, const ClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const ImageSubresourceRange* pRanges ) const
+    {
+      vkCmdClearDepthStencilImage( m_commandBuffer, static_cast<VkImage>( image ), static_cast<VkImageLayout>( imageLayout ), reinterpret_cast<const VkClearDepthStencilValue*>( pDepthStencil ), rangeCount, reinterpret_cast<const VkImageSubresourceRange*>( pRanges ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void clearDepthStencilImage( Image image, ImageLayout imageLayout, const ClearDepthStencilValue & depthStencil, ArrayProxy<const ImageSubresourceRange> ranges ) const
+    {
+      vkCmdClearDepthStencilImage( m_commandBuffer, static_cast<VkImage>( image ), static_cast<VkImageLayout>( imageLayout ), reinterpret_cast<const VkClearDepthStencilValue*>( &depthStencil ), ranges.size() , reinterpret_cast<const VkImageSubresourceRange*>( ranges.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void clearAttachments( uint32_t attachmentCount, const ClearAttachment* pAttachments, uint32_t rectCount, const ClearRect* pRects ) const
+    {
+      vkCmdClearAttachments( m_commandBuffer, attachmentCount, reinterpret_cast<const VkClearAttachment*>( pAttachments ), rectCount, reinterpret_cast<const VkClearRect*>( pRects ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void clearAttachments( ArrayProxy<const ClearAttachment> attachments, ArrayProxy<const ClearRect> rects ) const
+    {
+      vkCmdClearAttachments( m_commandBuffer, attachments.size() , reinterpret_cast<const VkClearAttachment*>( attachments.data() ), rects.size() , reinterpret_cast<const VkClearRect*>( rects.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void resolveImage( Image srcImage, ImageLayout srcImageLayout, Image dstImage, ImageLayout dstImageLayout, uint32_t regionCount, const ImageResolve* pRegions ) const
+    {
+      vkCmdResolveImage( m_commandBuffer, static_cast<VkImage>( srcImage ), static_cast<VkImageLayout>( srcImageLayout ), static_cast<VkImage>( dstImage ), static_cast<VkImageLayout>( dstImageLayout ), regionCount, reinterpret_cast<const VkImageResolve*>( pRegions ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void resolveImage( Image srcImage, ImageLayout srcImageLayout, Image dstImage, ImageLayout dstImageLayout, ArrayProxy<const ImageResolve> regions ) const
+    {
+      vkCmdResolveImage( m_commandBuffer, static_cast<VkImage>( srcImage ), static_cast<VkImageLayout>( srcImageLayout ), static_cast<VkImage>( dstImage ), static_cast<VkImageLayout>( dstImageLayout ), regions.size() , reinterpret_cast<const VkImageResolve*>( regions.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setEvent( Event event, PipelineStageFlags stageMask ) const
+    {
+      vkCmdSetEvent( m_commandBuffer, static_cast<VkEvent>( event ), static_cast<VkPipelineStageFlags>( stageMask ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void setEvent( Event event, PipelineStageFlags stageMask ) const
+    {
+      vkCmdSetEvent( m_commandBuffer, static_cast<VkEvent>( event ), static_cast<VkPipelineStageFlags>( stageMask ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void resetEvent( Event event, PipelineStageFlags stageMask ) const
+    {
+      vkCmdResetEvent( m_commandBuffer, static_cast<VkEvent>( event ), static_cast<VkPipelineStageFlags>( stageMask ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void resetEvent( Event event, PipelineStageFlags stageMask ) const
+    {
+      vkCmdResetEvent( m_commandBuffer, static_cast<VkEvent>( event ), static_cast<VkPipelineStageFlags>( stageMask ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void waitEvents( uint32_t eventCount, const Event* pEvents, PipelineStageFlags srcStageMask, PipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const MemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const BufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const ImageMemoryBarrier* pImageMemoryBarriers ) const
+    {
+      vkCmdWaitEvents( m_commandBuffer, eventCount, reinterpret_cast<const VkEvent*>( pEvents ), static_cast<VkPipelineStageFlags>( srcStageMask ), static_cast<VkPipelineStageFlags>( dstStageMask ), memoryBarrierCount, reinterpret_cast<const VkMemoryBarrier*>( pMemoryBarriers ), bufferMemoryBarrierCount, reinterpret_cast<const VkBufferMemoryBarrier*>( pBufferMemoryBarriers ), imageMemoryBarrierCount, reinterpret_cast<const VkImageMemoryBarrier*>( pImageMemoryBarriers ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void waitEvents( ArrayProxy<const Event> events, PipelineStageFlags srcStageMask, PipelineStageFlags dstStageMask, ArrayProxy<const MemoryBarrier> memoryBarriers, ArrayProxy<const BufferMemoryBarrier> bufferMemoryBarriers, ArrayProxy<const ImageMemoryBarrier> imageMemoryBarriers ) const
+    {
+      vkCmdWaitEvents( m_commandBuffer, events.size() , reinterpret_cast<const VkEvent*>( events.data() ), static_cast<VkPipelineStageFlags>( srcStageMask ), static_cast<VkPipelineStageFlags>( dstStageMask ), memoryBarriers.size() , reinterpret_cast<const VkMemoryBarrier*>( memoryBarriers.data() ), bufferMemoryBarriers.size() , reinterpret_cast<const VkBufferMemoryBarrier*>( bufferMemoryBarriers.data() ), imageMemoryBarriers.size() , reinterpret_cast<const VkImageMemoryBarrier*>( imageMemoryBarriers.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void pipelineBarrier( PipelineStageFlags srcStageMask, PipelineStageFlags dstStageMask, DependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const MemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const BufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const ImageMemoryBarrier* pImageMemoryBarriers ) const
+    {
+      vkCmdPipelineBarrier( m_commandBuffer, static_cast<VkPipelineStageFlags>( srcStageMask ), static_cast<VkPipelineStageFlags>( dstStageMask ), static_cast<VkDependencyFlags>( dependencyFlags ), memoryBarrierCount, reinterpret_cast<const VkMemoryBarrier*>( pMemoryBarriers ), bufferMemoryBarrierCount, reinterpret_cast<const VkBufferMemoryBarrier*>( pBufferMemoryBarriers ), imageMemoryBarrierCount, reinterpret_cast<const VkImageMemoryBarrier*>( pImageMemoryBarriers ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void pipelineBarrier( PipelineStageFlags srcStageMask, PipelineStageFlags dstStageMask, DependencyFlags dependencyFlags, ArrayProxy<const MemoryBarrier> memoryBarriers, ArrayProxy<const BufferMemoryBarrier> bufferMemoryBarriers, ArrayProxy<const ImageMemoryBarrier> imageMemoryBarriers ) const
+    {
+      vkCmdPipelineBarrier( m_commandBuffer, static_cast<VkPipelineStageFlags>( srcStageMask ), static_cast<VkPipelineStageFlags>( dstStageMask ), static_cast<VkDependencyFlags>( dependencyFlags ), memoryBarriers.size() , reinterpret_cast<const VkMemoryBarrier*>( memoryBarriers.data() ), bufferMemoryBarriers.size() , reinterpret_cast<const VkBufferMemoryBarrier*>( bufferMemoryBarriers.data() ), imageMemoryBarriers.size() , reinterpret_cast<const VkImageMemoryBarrier*>( imageMemoryBarriers.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void beginQuery( QueryPool queryPool, uint32_t query, QueryControlFlags flags ) const
+    {
+      vkCmdBeginQuery( m_commandBuffer, static_cast<VkQueryPool>( queryPool ), query, static_cast<VkQueryControlFlags>( flags ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void beginQuery( QueryPool queryPool, uint32_t query, QueryControlFlags flags ) const
+    {
+      vkCmdBeginQuery( m_commandBuffer, static_cast<VkQueryPool>( queryPool ), query, static_cast<VkQueryControlFlags>( flags ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void endQuery( QueryPool queryPool, uint32_t query ) const
+    {
+      vkCmdEndQuery( m_commandBuffer, static_cast<VkQueryPool>( queryPool ), query );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void endQuery( QueryPool queryPool, uint32_t query ) const
+    {
+      vkCmdEndQuery( m_commandBuffer, static_cast<VkQueryPool>( queryPool ), query );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void resetQueryPool( QueryPool queryPool, uint32_t firstQuery, uint32_t queryCount ) const
+    {
+      vkCmdResetQueryPool( m_commandBuffer, static_cast<VkQueryPool>( queryPool ), firstQuery, queryCount );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void resetQueryPool( QueryPool queryPool, uint32_t firstQuery, uint32_t queryCount ) const
+    {
+      vkCmdResetQueryPool( m_commandBuffer, static_cast<VkQueryPool>( queryPool ), firstQuery, queryCount );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void writeTimestamp( PipelineStageFlagBits pipelineStage, QueryPool queryPool, uint32_t query ) const
+    {
+      vkCmdWriteTimestamp( m_commandBuffer, static_cast<VkPipelineStageFlagBits>( pipelineStage ), static_cast<VkQueryPool>( queryPool ), query );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void writeTimestamp( PipelineStageFlagBits pipelineStage, QueryPool queryPool, uint32_t query ) const
+    {
+      vkCmdWriteTimestamp( m_commandBuffer, static_cast<VkPipelineStageFlagBits>( pipelineStage ), static_cast<VkQueryPool>( queryPool ), query );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void copyQueryPoolResults( QueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, Buffer dstBuffer, DeviceSize dstOffset, DeviceSize stride, QueryResultFlags flags ) const
+    {
+      vkCmdCopyQueryPoolResults( m_commandBuffer, static_cast<VkQueryPool>( queryPool ), firstQuery, queryCount, static_cast<VkBuffer>( dstBuffer ), dstOffset, stride, static_cast<VkQueryResultFlags>( flags ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void copyQueryPoolResults( QueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, Buffer dstBuffer, DeviceSize dstOffset, DeviceSize stride, QueryResultFlags flags ) const
+    {
+      vkCmdCopyQueryPoolResults( m_commandBuffer, static_cast<VkQueryPool>( queryPool ), firstQuery, queryCount, static_cast<VkBuffer>( dstBuffer ), dstOffset, stride, static_cast<VkQueryResultFlags>( flags ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void pushConstants( PipelineLayout layout, ShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues ) const
+    {
+      vkCmdPushConstants( m_commandBuffer, static_cast<VkPipelineLayout>( layout ), static_cast<VkShaderStageFlags>( stageFlags ), offset, size, pValues );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename T>
+    void pushConstants( PipelineLayout layout, ShaderStageFlags stageFlags, uint32_t offset, ArrayProxy<const T> values ) const
+    {
+      vkCmdPushConstants( m_commandBuffer, static_cast<VkPipelineLayout>( layout ), static_cast<VkShaderStageFlags>( stageFlags ), offset, values.size() * sizeof( T ) , reinterpret_cast<const void*>( values.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void beginRenderPass( const RenderPassBeginInfo* pRenderPassBegin, SubpassContents contents ) const
+    {
+      vkCmdBeginRenderPass( m_commandBuffer, reinterpret_cast<const VkRenderPassBeginInfo*>( pRenderPassBegin ), static_cast<VkSubpassContents>( contents ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void beginRenderPass( const RenderPassBeginInfo & renderPassBegin, SubpassContents contents ) const
+    {
+      vkCmdBeginRenderPass( m_commandBuffer, reinterpret_cast<const VkRenderPassBeginInfo*>( &renderPassBegin ), static_cast<VkSubpassContents>( contents ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void nextSubpass( SubpassContents contents ) const
+    {
+      vkCmdNextSubpass( m_commandBuffer, static_cast<VkSubpassContents>( contents ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void nextSubpass( SubpassContents contents ) const
+    {
+      vkCmdNextSubpass( m_commandBuffer, static_cast<VkSubpassContents>( contents ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void endRenderPass(  ) const
+    {
+      vkCmdEndRenderPass( m_commandBuffer );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void endRenderPass() const
+    {
+      vkCmdEndRenderPass( m_commandBuffer );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void executeCommands( uint32_t commandBufferCount, const CommandBuffer* pCommandBuffers ) const
+    {
+      vkCmdExecuteCommands( m_commandBuffer, commandBufferCount, reinterpret_cast<const VkCommandBuffer*>( pCommandBuffers ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void executeCommands( ArrayProxy<const CommandBuffer> commandBuffers ) const
+    {
+      vkCmdExecuteCommands( m_commandBuffer, commandBuffers.size() , reinterpret_cast<const VkCommandBuffer*>( commandBuffers.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void debugMarkerBeginEXT( DebugMarkerMarkerInfoEXT* pMarkerInfo ) const
+    {
+      vkCmdDebugMarkerBeginEXT( m_commandBuffer, reinterpret_cast<VkDebugMarkerMarkerInfoEXT*>( pMarkerInfo ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    DebugMarkerMarkerInfoEXT debugMarkerBeginEXT() const
+    {
+      DebugMarkerMarkerInfoEXT markerInfo;
+      vkCmdDebugMarkerBeginEXT( m_commandBuffer, reinterpret_cast<VkDebugMarkerMarkerInfoEXT*>( &markerInfo ) );
+      return markerInfo;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void debugMarkerEndEXT(  ) const
+    {
+      vkCmdDebugMarkerEndEXT( m_commandBuffer );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void debugMarkerEndEXT() const
+    {
+      vkCmdDebugMarkerEndEXT( m_commandBuffer );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void debugMarkerInsertEXT( DebugMarkerMarkerInfoEXT* pMarkerInfo ) const
+    {
+      vkCmdDebugMarkerInsertEXT( m_commandBuffer, reinterpret_cast<VkDebugMarkerMarkerInfoEXT*>( pMarkerInfo ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    DebugMarkerMarkerInfoEXT debugMarkerInsertEXT() const
+    {
+      DebugMarkerMarkerInfoEXT markerInfo;
+      vkCmdDebugMarkerInsertEXT( m_commandBuffer, reinterpret_cast<VkDebugMarkerMarkerInfoEXT*>( &markerInfo ) );
+      return markerInfo;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkCommandBuffer() const
+    {
+      return m_commandBuffer;
+    }
+
+    explicit operator bool() const
+    {
+      return m_commandBuffer != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_commandBuffer == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkCommandBuffer m_commandBuffer;
+  };
+  static_assert( sizeof( CommandBuffer ) == sizeof( VkCommandBuffer ), "handle and wrapper have different size!" );
+
+  struct SubpassDependency
+  {
+    SubpassDependency( uint32_t srcSubpass_ = 0, uint32_t dstSubpass_ = 0, PipelineStageFlags srcStageMask_ = PipelineStageFlags(), PipelineStageFlags dstStageMask_ = PipelineStageFlags(), AccessFlags srcAccessMask_ = AccessFlags(), AccessFlags dstAccessMask_ = AccessFlags(), DependencyFlags dependencyFlags_ = DependencyFlags() )
+      : srcSubpass( srcSubpass_ )
+      , dstSubpass( dstSubpass_ )
+      , srcStageMask( srcStageMask_ )
+      , dstStageMask( dstStageMask_ )
+      , srcAccessMask( srcAccessMask_ )
+      , dstAccessMask( dstAccessMask_ )
+      , dependencyFlags( dependencyFlags_ )
+    {
+    }
+
+    SubpassDependency( VkSubpassDependency const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SubpassDependency) );
+    }
+
+    SubpassDependency& operator=( VkSubpassDependency const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SubpassDependency) );
+      return *this;
+    }
+
+    SubpassDependency& setSrcSubpass( uint32_t srcSubpass_ )
+    {
+      srcSubpass = srcSubpass_;
+      return *this;
+    }
+
+    SubpassDependency& setDstSubpass( uint32_t dstSubpass_ )
+    {
+      dstSubpass = dstSubpass_;
+      return *this;
+    }
+
+    SubpassDependency& setSrcStageMask( PipelineStageFlags srcStageMask_ )
+    {
+      srcStageMask = srcStageMask_;
+      return *this;
+    }
+
+    SubpassDependency& setDstStageMask( PipelineStageFlags dstStageMask_ )
+    {
+      dstStageMask = dstStageMask_;
+      return *this;
+    }
+
+    SubpassDependency& setSrcAccessMask( AccessFlags srcAccessMask_ )
+    {
+      srcAccessMask = srcAccessMask_;
+      return *this;
+    }
+
+    SubpassDependency& setDstAccessMask( AccessFlags dstAccessMask_ )
+    {
+      dstAccessMask = dstAccessMask_;
+      return *this;
+    }
+
+    SubpassDependency& setDependencyFlags( DependencyFlags dependencyFlags_ )
+    {
+      dependencyFlags = dependencyFlags_;
+      return *this;
+    }
+
+    operator const VkSubpassDependency&() const
+    {
+      return *reinterpret_cast<const VkSubpassDependency*>(this);
+    }
+
+    bool operator==( SubpassDependency const& rhs ) const
+    {
+      return ( srcSubpass == rhs.srcSubpass )
+          && ( dstSubpass == rhs.dstSubpass )
+          && ( srcStageMask == rhs.srcStageMask )
+          && ( dstStageMask == rhs.dstStageMask )
+          && ( srcAccessMask == rhs.srcAccessMask )
+          && ( dstAccessMask == rhs.dstAccessMask )
+          && ( dependencyFlags == rhs.dependencyFlags );
+    }
+
+    bool operator!=( SubpassDependency const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t srcSubpass;
+    uint32_t dstSubpass;
+    PipelineStageFlags srcStageMask;
+    PipelineStageFlags dstStageMask;
+    AccessFlags srcAccessMask;
+    AccessFlags dstAccessMask;
+    DependencyFlags dependencyFlags;
+  };
+  static_assert( sizeof( SubpassDependency ) == sizeof( VkSubpassDependency ), "struct and wrapper have different size!" );
+
+  struct RenderPassCreateInfo
+  {
+    RenderPassCreateInfo( RenderPassCreateFlags flags_ = RenderPassCreateFlags(), uint32_t attachmentCount_ = 0, const AttachmentDescription* pAttachments_ = nullptr, uint32_t subpassCount_ = 0, const SubpassDescription* pSubpasses_ = nullptr, uint32_t dependencyCount_ = 0, const SubpassDependency* pDependencies_ = nullptr )
+      : sType( StructureType::eRenderPassCreateInfo )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , attachmentCount( attachmentCount_ )
+      , pAttachments( pAttachments_ )
+      , subpassCount( subpassCount_ )
+      , pSubpasses( pSubpasses_ )
+      , dependencyCount( dependencyCount_ )
+      , pDependencies( pDependencies_ )
+    {
+    }
+
+    RenderPassCreateInfo( VkRenderPassCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(RenderPassCreateInfo) );
+    }
+
+    RenderPassCreateInfo& operator=( VkRenderPassCreateInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(RenderPassCreateInfo) );
+      return *this;
+    }
+
+    RenderPassCreateInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    RenderPassCreateInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    RenderPassCreateInfo& setFlags( RenderPassCreateFlags flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    RenderPassCreateInfo& setAttachmentCount( uint32_t attachmentCount_ )
+    {
+      attachmentCount = attachmentCount_;
+      return *this;
+    }
+
+    RenderPassCreateInfo& setPAttachments( const AttachmentDescription* pAttachments_ )
+    {
+      pAttachments = pAttachments_;
+      return *this;
+    }
+
+    RenderPassCreateInfo& setSubpassCount( uint32_t subpassCount_ )
+    {
+      subpassCount = subpassCount_;
+      return *this;
+    }
+
+    RenderPassCreateInfo& setPSubpasses( const SubpassDescription* pSubpasses_ )
+    {
+      pSubpasses = pSubpasses_;
+      return *this;
+    }
+
+    RenderPassCreateInfo& setDependencyCount( uint32_t dependencyCount_ )
+    {
+      dependencyCount = dependencyCount_;
+      return *this;
+    }
+
+    RenderPassCreateInfo& setPDependencies( const SubpassDependency* pDependencies_ )
+    {
+      pDependencies = pDependencies_;
+      return *this;
+    }
+
+    operator const VkRenderPassCreateInfo&() const
+    {
+      return *reinterpret_cast<const VkRenderPassCreateInfo*>(this);
+    }
+
+    bool operator==( RenderPassCreateInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( attachmentCount == rhs.attachmentCount )
+          && ( pAttachments == rhs.pAttachments )
+          && ( subpassCount == rhs.subpassCount )
+          && ( pSubpasses == rhs.pSubpasses )
+          && ( dependencyCount == rhs.dependencyCount )
+          && ( pDependencies == rhs.pDependencies );
+    }
+
+    bool operator!=( RenderPassCreateInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    RenderPassCreateFlags flags;
+    uint32_t attachmentCount;
+    const AttachmentDescription* pAttachments;
+    uint32_t subpassCount;
+    const SubpassDescription* pSubpasses;
+    uint32_t dependencyCount;
+    const SubpassDependency* pDependencies;
+  };
+  static_assert( sizeof( RenderPassCreateInfo ) == sizeof( VkRenderPassCreateInfo ), "struct and wrapper have different size!" );
+
+  struct SubmitInfo
+  {
+    SubmitInfo( uint32_t waitSemaphoreCount_ = 0, const Semaphore* pWaitSemaphores_ = nullptr, const PipelineStageFlags* pWaitDstStageMask_ = nullptr, uint32_t commandBufferCount_ = 0, const CommandBuffer* pCommandBuffers_ = nullptr, uint32_t signalSemaphoreCount_ = 0, const Semaphore* pSignalSemaphores_ = nullptr )
+      : sType( StructureType::eSubmitInfo )
+      , pNext( nullptr )
+      , waitSemaphoreCount( waitSemaphoreCount_ )
+      , pWaitSemaphores( pWaitSemaphores_ )
+      , pWaitDstStageMask( pWaitDstStageMask_ )
+      , commandBufferCount( commandBufferCount_ )
+      , pCommandBuffers( pCommandBuffers_ )
+      , signalSemaphoreCount( signalSemaphoreCount_ )
+      , pSignalSemaphores( pSignalSemaphores_ )
+    {
+    }
+
+    SubmitInfo( VkSubmitInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SubmitInfo) );
+    }
+
+    SubmitInfo& operator=( VkSubmitInfo const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SubmitInfo) );
+      return *this;
+    }
+
+    SubmitInfo& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    SubmitInfo& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    SubmitInfo& setWaitSemaphoreCount( uint32_t waitSemaphoreCount_ )
+    {
+      waitSemaphoreCount = waitSemaphoreCount_;
+      return *this;
+    }
+
+    SubmitInfo& setPWaitSemaphores( const Semaphore* pWaitSemaphores_ )
+    {
+      pWaitSemaphores = pWaitSemaphores_;
+      return *this;
+    }
+
+    SubmitInfo& setPWaitDstStageMask( const PipelineStageFlags* pWaitDstStageMask_ )
+    {
+      pWaitDstStageMask = pWaitDstStageMask_;
+      return *this;
+    }
+
+    SubmitInfo& setCommandBufferCount( uint32_t commandBufferCount_ )
+    {
+      commandBufferCount = commandBufferCount_;
+      return *this;
+    }
+
+    SubmitInfo& setPCommandBuffers( const CommandBuffer* pCommandBuffers_ )
+    {
+      pCommandBuffers = pCommandBuffers_;
+      return *this;
+    }
+
+    SubmitInfo& setSignalSemaphoreCount( uint32_t signalSemaphoreCount_ )
+    {
+      signalSemaphoreCount = signalSemaphoreCount_;
+      return *this;
+    }
+
+    SubmitInfo& setPSignalSemaphores( const Semaphore* pSignalSemaphores_ )
+    {
+      pSignalSemaphores = pSignalSemaphores_;
+      return *this;
+    }
+
+    operator const VkSubmitInfo&() const
+    {
+      return *reinterpret_cast<const VkSubmitInfo*>(this);
+    }
+
+    bool operator==( SubmitInfo const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( waitSemaphoreCount == rhs.waitSemaphoreCount )
+          && ( pWaitSemaphores == rhs.pWaitSemaphores )
+          && ( pWaitDstStageMask == rhs.pWaitDstStageMask )
+          && ( commandBufferCount == rhs.commandBufferCount )
+          && ( pCommandBuffers == rhs.pCommandBuffers )
+          && ( signalSemaphoreCount == rhs.signalSemaphoreCount )
+          && ( pSignalSemaphores == rhs.pSignalSemaphores );
+    }
+
+    bool operator!=( SubmitInfo const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    uint32_t waitSemaphoreCount;
+    const Semaphore* pWaitSemaphores;
+    const PipelineStageFlags* pWaitDstStageMask;
+    uint32_t commandBufferCount;
+    const CommandBuffer* pCommandBuffers;
+    uint32_t signalSemaphoreCount;
+    const Semaphore* pSignalSemaphores;
+  };
+  static_assert( sizeof( SubmitInfo ) == sizeof( VkSubmitInfo ), "struct and wrapper have different size!" );
+
+  class Queue
+  {
+  public:
+    Queue()
+      : m_queue(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Queue(VkQueue queue)
+       : m_queue(queue)
+    {}
+
+    Queue& operator=(VkQueue queue)
+    {
+      m_queue = queue;
+      return *this;
+    }
+#endif
+
+    Result submit( uint32_t submitCount, const SubmitInfo* pSubmits, Fence fence ) const
+    {
+      return static_cast<Result>( vkQueueSubmit( m_queue, submitCount, reinterpret_cast<const VkSubmitInfo*>( pSubmits ), static_cast<VkFence>( fence ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type submit( ArrayProxy<const SubmitInfo> submits, Fence fence ) const
+    {
+      Result result = static_cast<Result>( vkQueueSubmit( m_queue, submits.size() , reinterpret_cast<const VkSubmitInfo*>( submits.data() ), static_cast<VkFence>( fence ) ) );
+      return createResultValue( result, "vk::Queue::submit" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result waitIdle(  ) const
+    {
+      return static_cast<Result>( vkQueueWaitIdle( m_queue ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type waitIdle() const
+    {
+      Result result = static_cast<Result>( vkQueueWaitIdle( m_queue ) );
+      return createResultValue( result, "vk::Queue::waitIdle" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result bindSparse( uint32_t bindInfoCount, const BindSparseInfo* pBindInfo, Fence fence ) const
+    {
+      return static_cast<Result>( vkQueueBindSparse( m_queue, bindInfoCount, reinterpret_cast<const VkBindSparseInfo*>( pBindInfo ), static_cast<VkFence>( fence ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type bindSparse( ArrayProxy<const BindSparseInfo> bindInfo, Fence fence ) const
+    {
+      Result result = static_cast<Result>( vkQueueBindSparse( m_queue, bindInfo.size() , reinterpret_cast<const VkBindSparseInfo*>( bindInfo.data() ), static_cast<VkFence>( fence ) ) );
+      return createResultValue( result, "vk::Queue::bindSparse" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result presentKHR( const PresentInfoKHR* pPresentInfo ) const
+    {
+      return static_cast<Result>( vkQueuePresentKHR( m_queue, reinterpret_cast<const VkPresentInfoKHR*>( pPresentInfo ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result presentKHR( const PresentInfoKHR & presentInfo ) const
+    {
+      Result result = static_cast<Result>( vkQueuePresentKHR( m_queue, reinterpret_cast<const VkPresentInfoKHR*>( &presentInfo ) ) );
+      return createResultValue( result, "vk::Queue::presentKHR", { Result::eSuccess, Result::eSuboptimalKHR } );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkQueue() const
+    {
+      return m_queue;
+    }
+
+    explicit operator bool() const
+    {
+      return m_queue != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_queue == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkQueue m_queue;
+  };
+  static_assert( sizeof( Queue ) == sizeof( VkQueue ), "handle and wrapper have different size!" );
+
+  enum class PresentModeKHR
+  {
+    eImmediate = VK_PRESENT_MODE_IMMEDIATE_KHR,
+    eMailbox = VK_PRESENT_MODE_MAILBOX_KHR,
+    eFifo = VK_PRESENT_MODE_FIFO_KHR,
+    eFifoRelaxed = VK_PRESENT_MODE_FIFO_RELAXED_KHR
+  };
+
+  enum class ColorSpaceKHR
+  {
+    eSrgbNonlinear = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
+  };
+
+  struct SurfaceFormatKHR
+  {
+    SurfaceFormatKHR( Format format_ = Format::eUndefined, ColorSpaceKHR colorSpace_ = ColorSpaceKHR::eSrgbNonlinear )
+      : format( format_ )
+      , colorSpace( colorSpace_ )
+    {
+    }
+
+    SurfaceFormatKHR( VkSurfaceFormatKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SurfaceFormatKHR) );
+    }
+
+    SurfaceFormatKHR& operator=( VkSurfaceFormatKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SurfaceFormatKHR) );
+      return *this;
+    }
+
+    SurfaceFormatKHR& setFormat( Format format_ )
+    {
+      format = format_;
+      return *this;
+    }
+
+    SurfaceFormatKHR& setColorSpace( ColorSpaceKHR colorSpace_ )
+    {
+      colorSpace = colorSpace_;
+      return *this;
+    }
+
+    operator const VkSurfaceFormatKHR&() const
+    {
+      return *reinterpret_cast<const VkSurfaceFormatKHR*>(this);
+    }
+
+    bool operator==( SurfaceFormatKHR const& rhs ) const
+    {
+      return ( format == rhs.format )
+          && ( colorSpace == rhs.colorSpace );
+    }
+
+    bool operator!=( SurfaceFormatKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    Format format;
+    ColorSpaceKHR colorSpace;
+  };
+  static_assert( sizeof( SurfaceFormatKHR ) == sizeof( VkSurfaceFormatKHR ), "struct and wrapper have different size!" );
+
+  enum class DisplayPlaneAlphaFlagBitsKHR
+  {
+    eOpaque = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR,
+    eGlobal = VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR,
+    ePerPixel = VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR,
+    ePerPixelPremultiplied = VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR
+  };
+
+  using DisplayPlaneAlphaFlagsKHR = Flags<DisplayPlaneAlphaFlagBitsKHR, VkDisplayPlaneAlphaFlagsKHR>;
+
+  inline DisplayPlaneAlphaFlagsKHR operator|( DisplayPlaneAlphaFlagBitsKHR bit0, DisplayPlaneAlphaFlagBitsKHR bit1 )
+  {
+    return DisplayPlaneAlphaFlagsKHR( bit0 ) | bit1;
+  }
+
+  struct DisplayPlaneCapabilitiesKHR
+  {
+    DisplayPlaneCapabilitiesKHR( DisplayPlaneAlphaFlagsKHR supportedAlpha_ = DisplayPlaneAlphaFlagsKHR(), Offset2D minSrcPosition_ = Offset2D(), Offset2D maxSrcPosition_ = Offset2D(), Extent2D minSrcExtent_ = Extent2D(), Extent2D maxSrcExtent_ = Extent2D(), Offset2D minDstPosition_ = Offset2D(), Offset2D maxDstPosition_ = Offset2D(), Extent2D minDstExtent_ = Extent2D(), Extent2D maxDstExtent_ = Extent2D() )
+      : supportedAlpha( supportedAlpha_ )
+      , minSrcPosition( minSrcPosition_ )
+      , maxSrcPosition( maxSrcPosition_ )
+      , minSrcExtent( minSrcExtent_ )
+      , maxSrcExtent( maxSrcExtent_ )
+      , minDstPosition( minDstPosition_ )
+      , maxDstPosition( maxDstPosition_ )
+      , minDstExtent( minDstExtent_ )
+      , maxDstExtent( maxDstExtent_ )
+    {
+    }
+
+    DisplayPlaneCapabilitiesKHR( VkDisplayPlaneCapabilitiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayPlaneCapabilitiesKHR) );
+    }
+
+    DisplayPlaneCapabilitiesKHR& operator=( VkDisplayPlaneCapabilitiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayPlaneCapabilitiesKHR) );
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setSupportedAlpha( DisplayPlaneAlphaFlagsKHR supportedAlpha_ )
+    {
+      supportedAlpha = supportedAlpha_;
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setMinSrcPosition( Offset2D minSrcPosition_ )
+    {
+      minSrcPosition = minSrcPosition_;
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setMaxSrcPosition( Offset2D maxSrcPosition_ )
+    {
+      maxSrcPosition = maxSrcPosition_;
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setMinSrcExtent( Extent2D minSrcExtent_ )
+    {
+      minSrcExtent = minSrcExtent_;
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setMaxSrcExtent( Extent2D maxSrcExtent_ )
+    {
+      maxSrcExtent = maxSrcExtent_;
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setMinDstPosition( Offset2D minDstPosition_ )
+    {
+      minDstPosition = minDstPosition_;
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setMaxDstPosition( Offset2D maxDstPosition_ )
+    {
+      maxDstPosition = maxDstPosition_;
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setMinDstExtent( Extent2D minDstExtent_ )
+    {
+      minDstExtent = minDstExtent_;
+      return *this;
+    }
+
+    DisplayPlaneCapabilitiesKHR& setMaxDstExtent( Extent2D maxDstExtent_ )
+    {
+      maxDstExtent = maxDstExtent_;
+      return *this;
+    }
+
+    operator const VkDisplayPlaneCapabilitiesKHR&() const
+    {
+      return *reinterpret_cast<const VkDisplayPlaneCapabilitiesKHR*>(this);
+    }
+
+    bool operator==( DisplayPlaneCapabilitiesKHR const& rhs ) const
+    {
+      return ( supportedAlpha == rhs.supportedAlpha )
+          && ( minSrcPosition == rhs.minSrcPosition )
+          && ( maxSrcPosition == rhs.maxSrcPosition )
+          && ( minSrcExtent == rhs.minSrcExtent )
+          && ( maxSrcExtent == rhs.maxSrcExtent )
+          && ( minDstPosition == rhs.minDstPosition )
+          && ( maxDstPosition == rhs.maxDstPosition )
+          && ( minDstExtent == rhs.minDstExtent )
+          && ( maxDstExtent == rhs.maxDstExtent );
+    }
+
+    bool operator!=( DisplayPlaneCapabilitiesKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DisplayPlaneAlphaFlagsKHR supportedAlpha;
+    Offset2D minSrcPosition;
+    Offset2D maxSrcPosition;
+    Extent2D minSrcExtent;
+    Extent2D maxSrcExtent;
+    Offset2D minDstPosition;
+    Offset2D maxDstPosition;
+    Extent2D minDstExtent;
+    Extent2D maxDstExtent;
+  };
+  static_assert( sizeof( DisplayPlaneCapabilitiesKHR ) == sizeof( VkDisplayPlaneCapabilitiesKHR ), "struct and wrapper have different size!" );
+
+  enum class CompositeAlphaFlagBitsKHR
+  {
+    eOpaque = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
+    ePreMultiplied = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
+    ePostMultiplied = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
+    eInherit = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR
+  };
+
+  using CompositeAlphaFlagsKHR = Flags<CompositeAlphaFlagBitsKHR, VkCompositeAlphaFlagsKHR>;
+
+  inline CompositeAlphaFlagsKHR operator|( CompositeAlphaFlagBitsKHR bit0, CompositeAlphaFlagBitsKHR bit1 )
+  {
+    return CompositeAlphaFlagsKHR( bit0 ) | bit1;
+  }
+
+  enum class SurfaceTransformFlagBitsKHR
+  {
+    eIdentity = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
+    eRotate90 = VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR,
+    eRotate180 = VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR,
+    eRotate270 = VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR,
+    eHorizontalMirror = VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR,
+    eHorizontalMirrorRotate90 = VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR,
+    eHorizontalMirrorRotate180 = VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR,
+    eHorizontalMirrorRotate270 = VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR,
+    eInherit = VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR
+  };
+
+  using SurfaceTransformFlagsKHR = Flags<SurfaceTransformFlagBitsKHR, VkSurfaceTransformFlagsKHR>;
+
+  inline SurfaceTransformFlagsKHR operator|( SurfaceTransformFlagBitsKHR bit0, SurfaceTransformFlagBitsKHR bit1 )
+  {
+    return SurfaceTransformFlagsKHR( bit0 ) | bit1;
+  }
+
+  struct DisplayPropertiesKHR
+  {
+    DisplayPropertiesKHR( DisplayKHR display_ = DisplayKHR(), const char* displayName_ = nullptr, Extent2D physicalDimensions_ = Extent2D(), Extent2D physicalResolution_ = Extent2D(), SurfaceTransformFlagsKHR supportedTransforms_ = SurfaceTransformFlagsKHR(), Bool32 planeReorderPossible_ = 0, Bool32 persistentContent_ = 0 )
+      : display( display_ )
+      , displayName( displayName_ )
+      , physicalDimensions( physicalDimensions_ )
+      , physicalResolution( physicalResolution_ )
+      , supportedTransforms( supportedTransforms_ )
+      , planeReorderPossible( planeReorderPossible_ )
+      , persistentContent( persistentContent_ )
+    {
+    }
+
+    DisplayPropertiesKHR( VkDisplayPropertiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayPropertiesKHR) );
+    }
+
+    DisplayPropertiesKHR& operator=( VkDisplayPropertiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplayPropertiesKHR) );
+      return *this;
+    }
+
+    DisplayPropertiesKHR& setDisplay( DisplayKHR display_ )
+    {
+      display = display_;
+      return *this;
+    }
+
+    DisplayPropertiesKHR& setDisplayName( const char* displayName_ )
+    {
+      displayName = displayName_;
+      return *this;
+    }
+
+    DisplayPropertiesKHR& setPhysicalDimensions( Extent2D physicalDimensions_ )
+    {
+      physicalDimensions = physicalDimensions_;
+      return *this;
+    }
+
+    DisplayPropertiesKHR& setPhysicalResolution( Extent2D physicalResolution_ )
+    {
+      physicalResolution = physicalResolution_;
+      return *this;
+    }
+
+    DisplayPropertiesKHR& setSupportedTransforms( SurfaceTransformFlagsKHR supportedTransforms_ )
+    {
+      supportedTransforms = supportedTransforms_;
+      return *this;
+    }
+
+    DisplayPropertiesKHR& setPlaneReorderPossible( Bool32 planeReorderPossible_ )
+    {
+      planeReorderPossible = planeReorderPossible_;
+      return *this;
+    }
+
+    DisplayPropertiesKHR& setPersistentContent( Bool32 persistentContent_ )
+    {
+      persistentContent = persistentContent_;
+      return *this;
+    }
+
+    operator const VkDisplayPropertiesKHR&() const
+    {
+      return *reinterpret_cast<const VkDisplayPropertiesKHR*>(this);
+    }
+
+    bool operator==( DisplayPropertiesKHR const& rhs ) const
+    {
+      return ( display == rhs.display )
+          && ( displayName == rhs.displayName )
+          && ( physicalDimensions == rhs.physicalDimensions )
+          && ( physicalResolution == rhs.physicalResolution )
+          && ( supportedTransforms == rhs.supportedTransforms )
+          && ( planeReorderPossible == rhs.planeReorderPossible )
+          && ( persistentContent == rhs.persistentContent );
+    }
+
+    bool operator!=( DisplayPropertiesKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    DisplayKHR display;
+    const char* displayName;
+    Extent2D physicalDimensions;
+    Extent2D physicalResolution;
+    SurfaceTransformFlagsKHR supportedTransforms;
+    Bool32 planeReorderPossible;
+    Bool32 persistentContent;
+  };
+  static_assert( sizeof( DisplayPropertiesKHR ) == sizeof( VkDisplayPropertiesKHR ), "struct and wrapper have different size!" );
+
+  struct DisplaySurfaceCreateInfoKHR
+  {
+    DisplaySurfaceCreateInfoKHR( DisplaySurfaceCreateFlagsKHR flags_ = DisplaySurfaceCreateFlagsKHR(), DisplayModeKHR displayMode_ = DisplayModeKHR(), uint32_t planeIndex_ = 0, uint32_t planeStackIndex_ = 0, SurfaceTransformFlagBitsKHR transform_ = SurfaceTransformFlagBitsKHR::eIdentity, float globalAlpha_ = 0, DisplayPlaneAlphaFlagBitsKHR alphaMode_ = DisplayPlaneAlphaFlagBitsKHR::eOpaque, Extent2D imageExtent_ = Extent2D() )
+      : sType( StructureType::eDisplaySurfaceCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , displayMode( displayMode_ )
+      , planeIndex( planeIndex_ )
+      , planeStackIndex( planeStackIndex_ )
+      , transform( transform_ )
+      , globalAlpha( globalAlpha_ )
+      , alphaMode( alphaMode_ )
+      , imageExtent( imageExtent_ )
+    {
+    }
+
+    DisplaySurfaceCreateInfoKHR( VkDisplaySurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplaySurfaceCreateInfoKHR) );
+    }
+
+    DisplaySurfaceCreateInfoKHR& operator=( VkDisplaySurfaceCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DisplaySurfaceCreateInfoKHR) );
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setFlags( DisplaySurfaceCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setDisplayMode( DisplayModeKHR displayMode_ )
+    {
+      displayMode = displayMode_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setPlaneIndex( uint32_t planeIndex_ )
+    {
+      planeIndex = planeIndex_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setPlaneStackIndex( uint32_t planeStackIndex_ )
+    {
+      planeStackIndex = planeStackIndex_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setTransform( SurfaceTransformFlagBitsKHR transform_ )
+    {
+      transform = transform_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setGlobalAlpha( float globalAlpha_ )
+    {
+      globalAlpha = globalAlpha_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setAlphaMode( DisplayPlaneAlphaFlagBitsKHR alphaMode_ )
+    {
+      alphaMode = alphaMode_;
+      return *this;
+    }
+
+    DisplaySurfaceCreateInfoKHR& setImageExtent( Extent2D imageExtent_ )
+    {
+      imageExtent = imageExtent_;
+      return *this;
+    }
+
+    operator const VkDisplaySurfaceCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkDisplaySurfaceCreateInfoKHR*>(this);
+    }
+
+    bool operator==( DisplaySurfaceCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( displayMode == rhs.displayMode )
+          && ( planeIndex == rhs.planeIndex )
+          && ( planeStackIndex == rhs.planeStackIndex )
+          && ( transform == rhs.transform )
+          && ( globalAlpha == rhs.globalAlpha )
+          && ( alphaMode == rhs.alphaMode )
+          && ( imageExtent == rhs.imageExtent );
+    }
+
+    bool operator!=( DisplaySurfaceCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DisplaySurfaceCreateFlagsKHR flags;
+    DisplayModeKHR displayMode;
+    uint32_t planeIndex;
+    uint32_t planeStackIndex;
+    SurfaceTransformFlagBitsKHR transform;
+    float globalAlpha;
+    DisplayPlaneAlphaFlagBitsKHR alphaMode;
+    Extent2D imageExtent;
+  };
+  static_assert( sizeof( DisplaySurfaceCreateInfoKHR ) == sizeof( VkDisplaySurfaceCreateInfoKHR ), "struct and wrapper have different size!" );
+
+  struct SurfaceCapabilitiesKHR
+  {
+    SurfaceCapabilitiesKHR( uint32_t minImageCount_ = 0, uint32_t maxImageCount_ = 0, Extent2D currentExtent_ = Extent2D(), Extent2D minImageExtent_ = Extent2D(), Extent2D maxImageExtent_ = Extent2D(), uint32_t maxImageArrayLayers_ = 0, SurfaceTransformFlagsKHR supportedTransforms_ = SurfaceTransformFlagsKHR(), SurfaceTransformFlagBitsKHR currentTransform_ = SurfaceTransformFlagBitsKHR::eIdentity, CompositeAlphaFlagsKHR supportedCompositeAlpha_ = CompositeAlphaFlagsKHR(), ImageUsageFlags supportedUsageFlags_ = ImageUsageFlags() )
+      : minImageCount( minImageCount_ )
+      , maxImageCount( maxImageCount_ )
+      , currentExtent( currentExtent_ )
+      , minImageExtent( minImageExtent_ )
+      , maxImageExtent( maxImageExtent_ )
+      , maxImageArrayLayers( maxImageArrayLayers_ )
+      , supportedTransforms( supportedTransforms_ )
+      , currentTransform( currentTransform_ )
+      , supportedCompositeAlpha( supportedCompositeAlpha_ )
+      , supportedUsageFlags( supportedUsageFlags_ )
+    {
+    }
+
+    SurfaceCapabilitiesKHR( VkSurfaceCapabilitiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SurfaceCapabilitiesKHR) );
+    }
+
+    SurfaceCapabilitiesKHR& operator=( VkSurfaceCapabilitiesKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SurfaceCapabilitiesKHR) );
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setMinImageCount( uint32_t minImageCount_ )
+    {
+      minImageCount = minImageCount_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setMaxImageCount( uint32_t maxImageCount_ )
+    {
+      maxImageCount = maxImageCount_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setCurrentExtent( Extent2D currentExtent_ )
+    {
+      currentExtent = currentExtent_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setMinImageExtent( Extent2D minImageExtent_ )
+    {
+      minImageExtent = minImageExtent_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setMaxImageExtent( Extent2D maxImageExtent_ )
+    {
+      maxImageExtent = maxImageExtent_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setMaxImageArrayLayers( uint32_t maxImageArrayLayers_ )
+    {
+      maxImageArrayLayers = maxImageArrayLayers_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setSupportedTransforms( SurfaceTransformFlagsKHR supportedTransforms_ )
+    {
+      supportedTransforms = supportedTransforms_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setCurrentTransform( SurfaceTransformFlagBitsKHR currentTransform_ )
+    {
+      currentTransform = currentTransform_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setSupportedCompositeAlpha( CompositeAlphaFlagsKHR supportedCompositeAlpha_ )
+    {
+      supportedCompositeAlpha = supportedCompositeAlpha_;
+      return *this;
+    }
+
+    SurfaceCapabilitiesKHR& setSupportedUsageFlags( ImageUsageFlags supportedUsageFlags_ )
+    {
+      supportedUsageFlags = supportedUsageFlags_;
+      return *this;
+    }
+
+    operator const VkSurfaceCapabilitiesKHR&() const
+    {
+      return *reinterpret_cast<const VkSurfaceCapabilitiesKHR*>(this);
+    }
+
+    bool operator==( SurfaceCapabilitiesKHR const& rhs ) const
+    {
+      return ( minImageCount == rhs.minImageCount )
+          && ( maxImageCount == rhs.maxImageCount )
+          && ( currentExtent == rhs.currentExtent )
+          && ( minImageExtent == rhs.minImageExtent )
+          && ( maxImageExtent == rhs.maxImageExtent )
+          && ( maxImageArrayLayers == rhs.maxImageArrayLayers )
+          && ( supportedTransforms == rhs.supportedTransforms )
+          && ( currentTransform == rhs.currentTransform )
+          && ( supportedCompositeAlpha == rhs.supportedCompositeAlpha )
+          && ( supportedUsageFlags == rhs.supportedUsageFlags );
+    }
+
+    bool operator!=( SurfaceCapabilitiesKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    uint32_t minImageCount;
+    uint32_t maxImageCount;
+    Extent2D currentExtent;
+    Extent2D minImageExtent;
+    Extent2D maxImageExtent;
+    uint32_t maxImageArrayLayers;
+    SurfaceTransformFlagsKHR supportedTransforms;
+    SurfaceTransformFlagBitsKHR currentTransform;
+    CompositeAlphaFlagsKHR supportedCompositeAlpha;
+    ImageUsageFlags supportedUsageFlags;
+  };
+  static_assert( sizeof( SurfaceCapabilitiesKHR ) == sizeof( VkSurfaceCapabilitiesKHR ), "struct and wrapper have different size!" );
+
+  struct SwapchainCreateInfoKHR
+  {
+    SwapchainCreateInfoKHR( SwapchainCreateFlagsKHR flags_ = SwapchainCreateFlagsKHR(), SurfaceKHR surface_ = SurfaceKHR(), uint32_t minImageCount_ = 0, Format imageFormat_ = Format::eUndefined, ColorSpaceKHR imageColorSpace_ = ColorSpaceKHR::eSrgbNonlinear, Extent2D imageExtent_ = Extent2D(), uint32_t imageArrayLayers_ = 0, ImageUsageFlags imageUsage_ = ImageUsageFlags(), SharingMode imageSharingMode_ = SharingMode::eExclusive, uint32_t queueFamilyIndexCount_ = 0, const uint32_t* pQueueFamilyIndices_ = nullptr, SurfaceTransformFlagBitsKHR preTransform_ = SurfaceTransformFlagBitsKHR::eIdentity, CompositeAlphaFlagBitsKHR compositeAlpha_ = CompositeAlphaFlagBitsKHR::eOpaque, PresentModeKHR presentMode_ = PresentModeKHR::eImmediate, Bool32 clipped_ = 0, SwapchainKHR oldSwapchain_ = SwapchainKHR() )
+      : sType( StructureType::eSwapchainCreateInfoKHR )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , surface( surface_ )
+      , minImageCount( minImageCount_ )
+      , imageFormat( imageFormat_ )
+      , imageColorSpace( imageColorSpace_ )
+      , imageExtent( imageExtent_ )
+      , imageArrayLayers( imageArrayLayers_ )
+      , imageUsage( imageUsage_ )
+      , imageSharingMode( imageSharingMode_ )
+      , queueFamilyIndexCount( queueFamilyIndexCount_ )
+      , pQueueFamilyIndices( pQueueFamilyIndices_ )
+      , preTransform( preTransform_ )
+      , compositeAlpha( compositeAlpha_ )
+      , presentMode( presentMode_ )
+      , clipped( clipped_ )
+      , oldSwapchain( oldSwapchain_ )
+    {
+    }
+
+    SwapchainCreateInfoKHR( VkSwapchainCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SwapchainCreateInfoKHR) );
+    }
+
+    SwapchainCreateInfoKHR& operator=( VkSwapchainCreateInfoKHR const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(SwapchainCreateInfoKHR) );
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setFlags( SwapchainCreateFlagsKHR flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setSurface( SurfaceKHR surface_ )
+    {
+      surface = surface_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setMinImageCount( uint32_t minImageCount_ )
+    {
+      minImageCount = minImageCount_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setImageFormat( Format imageFormat_ )
+    {
+      imageFormat = imageFormat_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setImageColorSpace( ColorSpaceKHR imageColorSpace_ )
+    {
+      imageColorSpace = imageColorSpace_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setImageExtent( Extent2D imageExtent_ )
+    {
+      imageExtent = imageExtent_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setImageArrayLayers( uint32_t imageArrayLayers_ )
+    {
+      imageArrayLayers = imageArrayLayers_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setImageUsage( ImageUsageFlags imageUsage_ )
+    {
+      imageUsage = imageUsage_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setImageSharingMode( SharingMode imageSharingMode_ )
+    {
+      imageSharingMode = imageSharingMode_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setQueueFamilyIndexCount( uint32_t queueFamilyIndexCount_ )
+    {
+      queueFamilyIndexCount = queueFamilyIndexCount_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setPQueueFamilyIndices( const uint32_t* pQueueFamilyIndices_ )
+    {
+      pQueueFamilyIndices = pQueueFamilyIndices_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setPreTransform( SurfaceTransformFlagBitsKHR preTransform_ )
+    {
+      preTransform = preTransform_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setCompositeAlpha( CompositeAlphaFlagBitsKHR compositeAlpha_ )
+    {
+      compositeAlpha = compositeAlpha_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setPresentMode( PresentModeKHR presentMode_ )
+    {
+      presentMode = presentMode_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setClipped( Bool32 clipped_ )
+    {
+      clipped = clipped_;
+      return *this;
+    }
+
+    SwapchainCreateInfoKHR& setOldSwapchain( SwapchainKHR oldSwapchain_ )
+    {
+      oldSwapchain = oldSwapchain_;
+      return *this;
+    }
+
+    operator const VkSwapchainCreateInfoKHR&() const
+    {
+      return *reinterpret_cast<const VkSwapchainCreateInfoKHR*>(this);
+    }
+
+    bool operator==( SwapchainCreateInfoKHR const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( surface == rhs.surface )
+          && ( minImageCount == rhs.minImageCount )
+          && ( imageFormat == rhs.imageFormat )
+          && ( imageColorSpace == rhs.imageColorSpace )
+          && ( imageExtent == rhs.imageExtent )
+          && ( imageArrayLayers == rhs.imageArrayLayers )
+          && ( imageUsage == rhs.imageUsage )
+          && ( imageSharingMode == rhs.imageSharingMode )
+          && ( queueFamilyIndexCount == rhs.queueFamilyIndexCount )
+          && ( pQueueFamilyIndices == rhs.pQueueFamilyIndices )
+          && ( preTransform == rhs.preTransform )
+          && ( compositeAlpha == rhs.compositeAlpha )
+          && ( presentMode == rhs.presentMode )
+          && ( clipped == rhs.clipped )
+          && ( oldSwapchain == rhs.oldSwapchain );
+    }
+
+    bool operator!=( SwapchainCreateInfoKHR const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    SwapchainCreateFlagsKHR flags;
+    SurfaceKHR surface;
+    uint32_t minImageCount;
+    Format imageFormat;
+    ColorSpaceKHR imageColorSpace;
+    Extent2D imageExtent;
+    uint32_t imageArrayLayers;
+    ImageUsageFlags imageUsage;
+    SharingMode imageSharingMode;
+    uint32_t queueFamilyIndexCount;
+    const uint32_t* pQueueFamilyIndices;
+    SurfaceTransformFlagBitsKHR preTransform;
+    CompositeAlphaFlagBitsKHR compositeAlpha;
+    PresentModeKHR presentMode;
+    Bool32 clipped;
+    SwapchainKHR oldSwapchain;
+  };
+  static_assert( sizeof( SwapchainCreateInfoKHR ) == sizeof( VkSwapchainCreateInfoKHR ), "struct and wrapper have different size!" );
+
+  enum class DebugReportFlagBitsEXT
+  {
+    eInformation = VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
+    eWarning = VK_DEBUG_REPORT_WARNING_BIT_EXT,
+    ePerformanceWarning = VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+    eError = VK_DEBUG_REPORT_ERROR_BIT_EXT,
+    eDebug = VK_DEBUG_REPORT_DEBUG_BIT_EXT
+  };
+
+  using DebugReportFlagsEXT = Flags<DebugReportFlagBitsEXT, VkDebugReportFlagsEXT>;
+
+  inline DebugReportFlagsEXT operator|( DebugReportFlagBitsEXT bit0, DebugReportFlagBitsEXT bit1 )
+  {
+    return DebugReportFlagsEXT( bit0 ) | bit1;
+  }
+
+  struct DebugReportCallbackCreateInfoEXT
+  {
+    DebugReportCallbackCreateInfoEXT( DebugReportFlagsEXT flags_ = DebugReportFlagsEXT(), PFN_vkDebugReportCallbackEXT pfnCallback_ = nullptr, void* pUserData_ = nullptr )
+      : sType( StructureType::eDebugReportCallbackCreateInfoEXT )
+      , pNext( nullptr )
+      , flags( flags_ )
+      , pfnCallback( pfnCallback_ )
+      , pUserData( pUserData_ )
+    {
+    }
+
+    DebugReportCallbackCreateInfoEXT( VkDebugReportCallbackCreateInfoEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DebugReportCallbackCreateInfoEXT) );
+    }
+
+    DebugReportCallbackCreateInfoEXT& operator=( VkDebugReportCallbackCreateInfoEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DebugReportCallbackCreateInfoEXT) );
+      return *this;
+    }
+
+    DebugReportCallbackCreateInfoEXT& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DebugReportCallbackCreateInfoEXT& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DebugReportCallbackCreateInfoEXT& setFlags( DebugReportFlagsEXT flags_ )
+    {
+      flags = flags_;
+      return *this;
+    }
+
+    DebugReportCallbackCreateInfoEXT& setPfnCallback( PFN_vkDebugReportCallbackEXT pfnCallback_ )
+    {
+      pfnCallback = pfnCallback_;
+      return *this;
+    }
+
+    DebugReportCallbackCreateInfoEXT& setPUserData( void* pUserData_ )
+    {
+      pUserData = pUserData_;
+      return *this;
+    }
+
+    operator const VkDebugReportCallbackCreateInfoEXT&() const
+    {
+      return *reinterpret_cast<const VkDebugReportCallbackCreateInfoEXT*>(this);
+    }
+
+    bool operator==( DebugReportCallbackCreateInfoEXT const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( flags == rhs.flags )
+          && ( pfnCallback == rhs.pfnCallback )
+          && ( pUserData == rhs.pUserData );
+    }
+
+    bool operator!=( DebugReportCallbackCreateInfoEXT const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DebugReportFlagsEXT flags;
+    PFN_vkDebugReportCallbackEXT pfnCallback;
+    void* pUserData;
+  };
+  static_assert( sizeof( DebugReportCallbackCreateInfoEXT ) == sizeof( VkDebugReportCallbackCreateInfoEXT ), "struct and wrapper have different size!" );
+
+  enum class DebugReportObjectTypeEXT
+  {
+    eUnknown = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+    eInstance = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
+    ePhysicalDevice = VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+    eDevice = VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
+    eQueue = VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
+    eSemaphore = VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
+    eCommandBuffer = VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+    eFence = VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
+    eDeviceMemory = VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+    eBuffer = VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
+    eImage = VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+    eEvent = VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,
+    eQueryPool = VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT,
+    eBufferView = VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT,
+    eImageView = VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT,
+    eShaderModule = VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
+    ePipelineCache = VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT,
+    ePipelineLayout = VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT,
+    eRenderPass = VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+    ePipeline = VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+    eDescriptorSetLayout = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT,
+    eSampler = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT,
+    eDescriptorPool = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
+    eDescriptorSet = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
+    eFramebuffer = VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT,
+    eCommandPool = VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT,
+    eSurfaceKhr = VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT,
+    eSwapchainKhr = VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
+    eDebugReport = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT
+  };
+
+  struct DebugMarkerObjectNameInfoEXT
+  {
+    DebugMarkerObjectNameInfoEXT( DebugReportObjectTypeEXT objectType_ = DebugReportObjectTypeEXT::eUnknown, uint64_t object_ = 0, const char* pObjectName_ = nullptr )
+      : sType( StructureType::eDebugMarkerObjectNameInfoEXT )
+      , pNext( nullptr )
+      , objectType( objectType_ )
+      , object( object_ )
+      , pObjectName( pObjectName_ )
+    {
+    }
+
+    DebugMarkerObjectNameInfoEXT( VkDebugMarkerObjectNameInfoEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DebugMarkerObjectNameInfoEXT) );
+    }
+
+    DebugMarkerObjectNameInfoEXT& operator=( VkDebugMarkerObjectNameInfoEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DebugMarkerObjectNameInfoEXT) );
+      return *this;
+    }
+
+    DebugMarkerObjectNameInfoEXT& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DebugMarkerObjectNameInfoEXT& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DebugMarkerObjectNameInfoEXT& setObjectType( DebugReportObjectTypeEXT objectType_ )
+    {
+      objectType = objectType_;
+      return *this;
+    }
+
+    DebugMarkerObjectNameInfoEXT& setObject( uint64_t object_ )
+    {
+      object = object_;
+      return *this;
+    }
+
+    DebugMarkerObjectNameInfoEXT& setPObjectName( const char* pObjectName_ )
+    {
+      pObjectName = pObjectName_;
+      return *this;
+    }
+
+    operator const VkDebugMarkerObjectNameInfoEXT&() const
+    {
+      return *reinterpret_cast<const VkDebugMarkerObjectNameInfoEXT*>(this);
+    }
+
+    bool operator==( DebugMarkerObjectNameInfoEXT const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( objectType == rhs.objectType )
+          && ( object == rhs.object )
+          && ( pObjectName == rhs.pObjectName );
+    }
+
+    bool operator!=( DebugMarkerObjectNameInfoEXT const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DebugReportObjectTypeEXT objectType;
+    uint64_t object;
+    const char* pObjectName;
+  };
+  static_assert( sizeof( DebugMarkerObjectNameInfoEXT ) == sizeof( VkDebugMarkerObjectNameInfoEXT ), "struct and wrapper have different size!" );
+
+  struct DebugMarkerObjectTagInfoEXT
+  {
+    DebugMarkerObjectTagInfoEXT( DebugReportObjectTypeEXT objectType_ = DebugReportObjectTypeEXT::eUnknown, uint64_t object_ = 0, uint64_t tagName_ = 0, size_t tagSize_ = 0, const void* pTag_ = nullptr )
+      : sType( StructureType::eDebugMarkerObjectTagInfoEXT )
+      , pNext( nullptr )
+      , objectType( objectType_ )
+      , object( object_ )
+      , tagName( tagName_ )
+      , tagSize( tagSize_ )
+      , pTag( pTag_ )
+    {
+    }
+
+    DebugMarkerObjectTagInfoEXT( VkDebugMarkerObjectTagInfoEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DebugMarkerObjectTagInfoEXT) );
+    }
+
+    DebugMarkerObjectTagInfoEXT& operator=( VkDebugMarkerObjectTagInfoEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(DebugMarkerObjectTagInfoEXT) );
+      return *this;
+    }
+
+    DebugMarkerObjectTagInfoEXT& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    DebugMarkerObjectTagInfoEXT& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    DebugMarkerObjectTagInfoEXT& setObjectType( DebugReportObjectTypeEXT objectType_ )
+    {
+      objectType = objectType_;
+      return *this;
+    }
+
+    DebugMarkerObjectTagInfoEXT& setObject( uint64_t object_ )
+    {
+      object = object_;
+      return *this;
+    }
+
+    DebugMarkerObjectTagInfoEXT& setTagName( uint64_t tagName_ )
+    {
+      tagName = tagName_;
+      return *this;
+    }
+
+    DebugMarkerObjectTagInfoEXT& setTagSize( size_t tagSize_ )
+    {
+      tagSize = tagSize_;
+      return *this;
+    }
+
+    DebugMarkerObjectTagInfoEXT& setPTag( const void* pTag_ )
+    {
+      pTag = pTag_;
+      return *this;
+    }
+
+    operator const VkDebugMarkerObjectTagInfoEXT&() const
+    {
+      return *reinterpret_cast<const VkDebugMarkerObjectTagInfoEXT*>(this);
+    }
+
+    bool operator==( DebugMarkerObjectTagInfoEXT const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( objectType == rhs.objectType )
+          && ( object == rhs.object )
+          && ( tagName == rhs.tagName )
+          && ( tagSize == rhs.tagSize )
+          && ( pTag == rhs.pTag );
+    }
+
+    bool operator!=( DebugMarkerObjectTagInfoEXT const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    DebugReportObjectTypeEXT objectType;
+    uint64_t object;
+    uint64_t tagName;
+    size_t tagSize;
+    const void* pTag;
+  };
+  static_assert( sizeof( DebugMarkerObjectTagInfoEXT ) == sizeof( VkDebugMarkerObjectTagInfoEXT ), "struct and wrapper have different size!" );
+
+  class Device
+  {
+  public:
+    Device()
+      : m_device(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Device(VkDevice device)
+       : m_device(device)
+    {}
+
+    Device& operator=(VkDevice device)
+    {
+      m_device = device;
+      return *this;
+    }
+#endif
+
+    PFN_vkVoidFunction getProcAddr( const char* pName ) const
+    {
+      return vkGetDeviceProcAddr( m_device, pName );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    PFN_vkVoidFunction getProcAddr( const std::string & name ) const
+    {
+      return vkGetDeviceProcAddr( m_device, name.c_str() );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroy( const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyDevice( m_device, reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroy( Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyDevice( m_device, reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getQueue( uint32_t queueFamilyIndex, uint32_t queueIndex, Queue* pQueue ) const
+    {
+      vkGetDeviceQueue( m_device, queueFamilyIndex, queueIndex, reinterpret_cast<VkQueue*>( pQueue ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Queue getQueue( uint32_t queueFamilyIndex, uint32_t queueIndex ) const
+    {
+      Queue queue;
+      vkGetDeviceQueue( m_device, queueFamilyIndex, queueIndex, reinterpret_cast<VkQueue*>( &queue ) );
+      return queue;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result waitIdle(  ) const
+    {
+      return static_cast<Result>( vkDeviceWaitIdle( m_device ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type waitIdle() const
+    {
+      Result result = static_cast<Result>( vkDeviceWaitIdle( m_device ) );
+      return createResultValue( result, "vk::Device::waitIdle" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result allocateMemory( const MemoryAllocateInfo* pAllocateInfo, const AllocationCallbacks* pAllocator, DeviceMemory* pMemory ) const
+    {
+      return static_cast<Result>( vkAllocateMemory( m_device, reinterpret_cast<const VkMemoryAllocateInfo*>( pAllocateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkDeviceMemory*>( pMemory ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<DeviceMemory>::type allocateMemory( const MemoryAllocateInfo & allocateInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      DeviceMemory memory;
+      Result result = static_cast<Result>( vkAllocateMemory( m_device, reinterpret_cast<const VkMemoryAllocateInfo*>( &allocateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkDeviceMemory*>( &memory ) ) );
+      return createResultValue( result, memory, "vk::Device::allocateMemory" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void freeMemory( DeviceMemory memory, const AllocationCallbacks* pAllocator ) const
+    {
+      vkFreeMemory( m_device, static_cast<VkDeviceMemory>( memory ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void freeMemory( DeviceMemory memory, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkFreeMemory( m_device, static_cast<VkDeviceMemory>( memory ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result mapMemory( DeviceMemory memory, DeviceSize offset, DeviceSize size, MemoryMapFlags flags, void** ppData ) const
+    {
+      return static_cast<Result>( vkMapMemory( m_device, static_cast<VkDeviceMemory>( memory ), offset, size, static_cast<VkMemoryMapFlags>( flags ), ppData ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void*>::type mapMemory( DeviceMemory memory, DeviceSize offset, DeviceSize size, MemoryMapFlags flags = MemoryMapFlags() ) const
+    {
+      void* pData;
+      Result result = static_cast<Result>( vkMapMemory( m_device, static_cast<VkDeviceMemory>( memory ), offset, size, static_cast<VkMemoryMapFlags>( flags ), &pData ) );
+      return createResultValue( result, pData, "vk::Device::mapMemory" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void unmapMemory( DeviceMemory memory ) const
+    {
+      vkUnmapMemory( m_device, static_cast<VkDeviceMemory>( memory ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void unmapMemory( DeviceMemory memory ) const
+    {
+      vkUnmapMemory( m_device, static_cast<VkDeviceMemory>( memory ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result flushMappedMemoryRanges( uint32_t memoryRangeCount, const MappedMemoryRange* pMemoryRanges ) const
+    {
+      return static_cast<Result>( vkFlushMappedMemoryRanges( m_device, memoryRangeCount, reinterpret_cast<const VkMappedMemoryRange*>( pMemoryRanges ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type flushMappedMemoryRanges( ArrayProxy<const MappedMemoryRange> memoryRanges ) const
+    {
+      Result result = static_cast<Result>( vkFlushMappedMemoryRanges( m_device, memoryRanges.size() , reinterpret_cast<const VkMappedMemoryRange*>( memoryRanges.data() ) ) );
+      return createResultValue( result, "vk::Device::flushMappedMemoryRanges" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result invalidateMappedMemoryRanges( uint32_t memoryRangeCount, const MappedMemoryRange* pMemoryRanges ) const
+    {
+      return static_cast<Result>( vkInvalidateMappedMemoryRanges( m_device, memoryRangeCount, reinterpret_cast<const VkMappedMemoryRange*>( pMemoryRanges ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type invalidateMappedMemoryRanges( ArrayProxy<const MappedMemoryRange> memoryRanges ) const
+    {
+      Result result = static_cast<Result>( vkInvalidateMappedMemoryRanges( m_device, memoryRanges.size() , reinterpret_cast<const VkMappedMemoryRange*>( memoryRanges.data() ) ) );
+      return createResultValue( result, "vk::Device::invalidateMappedMemoryRanges" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getMemoryCommitment( DeviceMemory memory, DeviceSize* pCommittedMemoryInBytes ) const
+    {
+      vkGetDeviceMemoryCommitment( m_device, static_cast<VkDeviceMemory>( memory ), pCommittedMemoryInBytes );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    DeviceSize getMemoryCommitment( DeviceMemory memory ) const
+    {
+      DeviceSize committedMemoryInBytes;
+      vkGetDeviceMemoryCommitment( m_device, static_cast<VkDeviceMemory>( memory ), &committedMemoryInBytes );
+      return committedMemoryInBytes;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getBufferMemoryRequirements( Buffer buffer, MemoryRequirements* pMemoryRequirements ) const
+    {
+      vkGetBufferMemoryRequirements( m_device, static_cast<VkBuffer>( buffer ), reinterpret_cast<VkMemoryRequirements*>( pMemoryRequirements ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    MemoryRequirements getBufferMemoryRequirements( Buffer buffer ) const
+    {
+      MemoryRequirements memoryRequirements;
+      vkGetBufferMemoryRequirements( m_device, static_cast<VkBuffer>( buffer ), reinterpret_cast<VkMemoryRequirements*>( &memoryRequirements ) );
+      return memoryRequirements;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result bindBufferMemory( Buffer buffer, DeviceMemory memory, DeviceSize memoryOffset ) const
+    {
+      return static_cast<Result>( vkBindBufferMemory( m_device, static_cast<VkBuffer>( buffer ), static_cast<VkDeviceMemory>( memory ), memoryOffset ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type bindBufferMemory( Buffer buffer, DeviceMemory memory, DeviceSize memoryOffset ) const
+    {
+      Result result = static_cast<Result>( vkBindBufferMemory( m_device, static_cast<VkBuffer>( buffer ), static_cast<VkDeviceMemory>( memory ), memoryOffset ) );
+      return createResultValue( result, "vk::Device::bindBufferMemory" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getImageMemoryRequirements( Image image, MemoryRequirements* pMemoryRequirements ) const
+    {
+      vkGetImageMemoryRequirements( m_device, static_cast<VkImage>( image ), reinterpret_cast<VkMemoryRequirements*>( pMemoryRequirements ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    MemoryRequirements getImageMemoryRequirements( Image image ) const
+    {
+      MemoryRequirements memoryRequirements;
+      vkGetImageMemoryRequirements( m_device, static_cast<VkImage>( image ), reinterpret_cast<VkMemoryRequirements*>( &memoryRequirements ) );
+      return memoryRequirements;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result bindImageMemory( Image image, DeviceMemory memory, DeviceSize memoryOffset ) const
+    {
+      return static_cast<Result>( vkBindImageMemory( m_device, static_cast<VkImage>( image ), static_cast<VkDeviceMemory>( memory ), memoryOffset ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type bindImageMemory( Image image, DeviceMemory memory, DeviceSize memoryOffset ) const
+    {
+      Result result = static_cast<Result>( vkBindImageMemory( m_device, static_cast<VkImage>( image ), static_cast<VkDeviceMemory>( memory ), memoryOffset ) );
+      return createResultValue( result, "vk::Device::bindImageMemory" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getImageSparseMemoryRequirements( Image image, uint32_t* pSparseMemoryRequirementCount, SparseImageMemoryRequirements* pSparseMemoryRequirements ) const
+    {
+      vkGetImageSparseMemoryRequirements( m_device, static_cast<VkImage>( image ), pSparseMemoryRequirementCount, reinterpret_cast<VkSparseImageMemoryRequirements*>( pSparseMemoryRequirements ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<SparseImageMemoryRequirements>>
+    std::vector<SparseImageMemoryRequirements,Allocator> getImageSparseMemoryRequirements( Image image ) const
+    {
+      std::vector<SparseImageMemoryRequirements,Allocator> sparseMemoryRequirements;
+      uint32_t sparseMemoryRequirementCount;
+      vkGetImageSparseMemoryRequirements( m_device, static_cast<VkImage>( image ), &sparseMemoryRequirementCount, nullptr );
+      sparseMemoryRequirements.resize( sparseMemoryRequirementCount );
+      vkGetImageSparseMemoryRequirements( m_device, static_cast<VkImage>( image ), &sparseMemoryRequirementCount, reinterpret_cast<VkSparseImageMemoryRequirements*>( sparseMemoryRequirements.data() ) );
+      return sparseMemoryRequirements;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createFence( const FenceCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Fence* pFence ) const
+    {
+      return static_cast<Result>( vkCreateFence( m_device, reinterpret_cast<const VkFenceCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkFence*>( pFence ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Fence>::type createFence( const FenceCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Fence fence;
+      Result result = static_cast<Result>( vkCreateFence( m_device, reinterpret_cast<const VkFenceCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkFence*>( &fence ) ) );
+      return createResultValue( result, fence, "vk::Device::createFence" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyFence( Fence fence, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyFence( m_device, static_cast<VkFence>( fence ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyFence( Fence fence, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyFence( m_device, static_cast<VkFence>( fence ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result resetFences( uint32_t fenceCount, const Fence* pFences ) const
+    {
+      return static_cast<Result>( vkResetFences( m_device, fenceCount, reinterpret_cast<const VkFence*>( pFences ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type resetFences( ArrayProxy<const Fence> fences ) const
+    {
+      Result result = static_cast<Result>( vkResetFences( m_device, fences.size() , reinterpret_cast<const VkFence*>( fences.data() ) ) );
+      return createResultValue( result, "vk::Device::resetFences" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result getFenceStatus( Fence fence ) const
+    {
+      return static_cast<Result>( vkGetFenceStatus( m_device, static_cast<VkFence>( fence ) ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result getFenceStatus( Fence fence ) const
+    {
+      Result result = static_cast<Result>( vkGetFenceStatus( m_device, static_cast<VkFence>( fence ) ) );
+      return createResultValue( result, "vk::Device::getFenceStatus", { Result::eSuccess, Result::eNotReady } );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result waitForFences( uint32_t fenceCount, const Fence* pFences, Bool32 waitAll, uint64_t timeout ) const
+    {
+      return static_cast<Result>( vkWaitForFences( m_device, fenceCount, reinterpret_cast<const VkFence*>( pFences ), waitAll, timeout ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result waitForFences( ArrayProxy<const Fence> fences, Bool32 waitAll, uint64_t timeout ) const
+    {
+      Result result = static_cast<Result>( vkWaitForFences( m_device, fences.size() , reinterpret_cast<const VkFence*>( fences.data() ), waitAll, timeout ) );
+      return createResultValue( result, "vk::Device::waitForFences", { Result::eSuccess, Result::eTimeout } );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createSemaphore( const SemaphoreCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Semaphore* pSemaphore ) const
+    {
+      return static_cast<Result>( vkCreateSemaphore( m_device, reinterpret_cast<const VkSemaphoreCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSemaphore*>( pSemaphore ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Semaphore>::type createSemaphore( const SemaphoreCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Semaphore semaphore;
+      Result result = static_cast<Result>( vkCreateSemaphore( m_device, reinterpret_cast<const VkSemaphoreCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSemaphore*>( &semaphore ) ) );
+      return createResultValue( result, semaphore, "vk::Device::createSemaphore" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroySemaphore( Semaphore semaphore, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroySemaphore( m_device, static_cast<VkSemaphore>( semaphore ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroySemaphore( Semaphore semaphore, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroySemaphore( m_device, static_cast<VkSemaphore>( semaphore ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createEvent( const EventCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Event* pEvent ) const
+    {
+      return static_cast<Result>( vkCreateEvent( m_device, reinterpret_cast<const VkEventCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkEvent*>( pEvent ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Event>::type createEvent( const EventCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Event event;
+      Result result = static_cast<Result>( vkCreateEvent( m_device, reinterpret_cast<const VkEventCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkEvent*>( &event ) ) );
+      return createResultValue( result, event, "vk::Device::createEvent" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyEvent( Event event, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyEvent( m_device, static_cast<VkEvent>( event ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyEvent( Event event, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyEvent( m_device, static_cast<VkEvent>( event ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result getEventStatus( Event event ) const
+    {
+      return static_cast<Result>( vkGetEventStatus( m_device, static_cast<VkEvent>( event ) ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result getEventStatus( Event event ) const
+    {
+      Result result = static_cast<Result>( vkGetEventStatus( m_device, static_cast<VkEvent>( event ) ) );
+      return createResultValue( result, "vk::Device::getEventStatus", { Result::eEventSet, Result::eEventReset } );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result setEvent( Event event ) const
+    {
+      return static_cast<Result>( vkSetEvent( m_device, static_cast<VkEvent>( event ) ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type setEvent( Event event ) const
+    {
+      Result result = static_cast<Result>( vkSetEvent( m_device, static_cast<VkEvent>( event ) ) );
+      return createResultValue( result, "vk::Device::setEvent" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result resetEvent( Event event ) const
+    {
+      return static_cast<Result>( vkResetEvent( m_device, static_cast<VkEvent>( event ) ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type resetEvent( Event event ) const
+    {
+      Result result = static_cast<Result>( vkResetEvent( m_device, static_cast<VkEvent>( event ) ) );
+      return createResultValue( result, "vk::Device::resetEvent" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createQueryPool( const QueryPoolCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, QueryPool* pQueryPool ) const
+    {
+      return static_cast<Result>( vkCreateQueryPool( m_device, reinterpret_cast<const VkQueryPoolCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkQueryPool*>( pQueryPool ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<QueryPool>::type createQueryPool( const QueryPoolCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      QueryPool queryPool;
+      Result result = static_cast<Result>( vkCreateQueryPool( m_device, reinterpret_cast<const VkQueryPoolCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkQueryPool*>( &queryPool ) ) );
+      return createResultValue( result, queryPool, "vk::Device::createQueryPool" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyQueryPool( QueryPool queryPool, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyQueryPool( m_device, static_cast<VkQueryPool>( queryPool ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyQueryPool( QueryPool queryPool, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyQueryPool( m_device, static_cast<VkQueryPool>( queryPool ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getQueryPoolResults( QueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, DeviceSize stride, QueryResultFlags flags ) const
+    {
+      return static_cast<Result>( vkGetQueryPoolResults( m_device, static_cast<VkQueryPool>( queryPool ), firstQuery, queryCount, dataSize, pData, stride, static_cast<VkQueryResultFlags>( flags ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename T>
+    Result getQueryPoolResults( QueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, ArrayProxy<T> data, DeviceSize stride, QueryResultFlags flags ) const
+    {
+      Result result = static_cast<Result>( vkGetQueryPoolResults( m_device, static_cast<VkQueryPool>( queryPool ), firstQuery, queryCount, data.size() * sizeof( T ) , reinterpret_cast<void*>( data.data() ), stride, static_cast<VkQueryResultFlags>( flags ) ) );
+      return createResultValue( result, "vk::Device::getQueryPoolResults", { Result::eSuccess, Result::eNotReady } );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createBuffer( const BufferCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Buffer* pBuffer ) const
+    {
+      return static_cast<Result>( vkCreateBuffer( m_device, reinterpret_cast<const VkBufferCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkBuffer*>( pBuffer ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Buffer>::type createBuffer( const BufferCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Buffer buffer;
+      Result result = static_cast<Result>( vkCreateBuffer( m_device, reinterpret_cast<const VkBufferCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkBuffer*>( &buffer ) ) );
+      return createResultValue( result, buffer, "vk::Device::createBuffer" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyBuffer( Buffer buffer, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyBuffer( m_device, static_cast<VkBuffer>( buffer ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyBuffer( Buffer buffer, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyBuffer( m_device, static_cast<VkBuffer>( buffer ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createBufferView( const BufferViewCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, BufferView* pView ) const
+    {
+      return static_cast<Result>( vkCreateBufferView( m_device, reinterpret_cast<const VkBufferViewCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkBufferView*>( pView ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<BufferView>::type createBufferView( const BufferViewCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      BufferView view;
+      Result result = static_cast<Result>( vkCreateBufferView( m_device, reinterpret_cast<const VkBufferViewCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkBufferView*>( &view ) ) );
+      return createResultValue( result, view, "vk::Device::createBufferView" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyBufferView( BufferView bufferView, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyBufferView( m_device, static_cast<VkBufferView>( bufferView ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyBufferView( BufferView bufferView, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyBufferView( m_device, static_cast<VkBufferView>( bufferView ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createImage( const ImageCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Image* pImage ) const
+    {
+      return static_cast<Result>( vkCreateImage( m_device, reinterpret_cast<const VkImageCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkImage*>( pImage ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Image>::type createImage( const ImageCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Image image;
+      Result result = static_cast<Result>( vkCreateImage( m_device, reinterpret_cast<const VkImageCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkImage*>( &image ) ) );
+      return createResultValue( result, image, "vk::Device::createImage" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyImage( Image image, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyImage( m_device, static_cast<VkImage>( image ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyImage( Image image, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyImage( m_device, static_cast<VkImage>( image ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getImageSubresourceLayout( Image image, const ImageSubresource* pSubresource, SubresourceLayout* pLayout ) const
+    {
+      vkGetImageSubresourceLayout( m_device, static_cast<VkImage>( image ), reinterpret_cast<const VkImageSubresource*>( pSubresource ), reinterpret_cast<VkSubresourceLayout*>( pLayout ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    SubresourceLayout getImageSubresourceLayout( Image image, const ImageSubresource & subresource ) const
+    {
+      SubresourceLayout layout;
+      vkGetImageSubresourceLayout( m_device, static_cast<VkImage>( image ), reinterpret_cast<const VkImageSubresource*>( &subresource ), reinterpret_cast<VkSubresourceLayout*>( &layout ) );
+      return layout;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createImageView( const ImageViewCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, ImageView* pView ) const
+    {
+      return static_cast<Result>( vkCreateImageView( m_device, reinterpret_cast<const VkImageViewCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkImageView*>( pView ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<ImageView>::type createImageView( const ImageViewCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      ImageView view;
+      Result result = static_cast<Result>( vkCreateImageView( m_device, reinterpret_cast<const VkImageViewCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkImageView*>( &view ) ) );
+      return createResultValue( result, view, "vk::Device::createImageView" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyImageView( ImageView imageView, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyImageView( m_device, static_cast<VkImageView>( imageView ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyImageView( ImageView imageView, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyImageView( m_device, static_cast<VkImageView>( imageView ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createShaderModule( const ShaderModuleCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, ShaderModule* pShaderModule ) const
+    {
+      return static_cast<Result>( vkCreateShaderModule( m_device, reinterpret_cast<const VkShaderModuleCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkShaderModule*>( pShaderModule ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<ShaderModule>::type createShaderModule( const ShaderModuleCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      ShaderModule shaderModule;
+      Result result = static_cast<Result>( vkCreateShaderModule( m_device, reinterpret_cast<const VkShaderModuleCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkShaderModule*>( &shaderModule ) ) );
+      return createResultValue( result, shaderModule, "vk::Device::createShaderModule" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyShaderModule( ShaderModule shaderModule, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyShaderModule( m_device, static_cast<VkShaderModule>( shaderModule ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyShaderModule( ShaderModule shaderModule, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyShaderModule( m_device, static_cast<VkShaderModule>( shaderModule ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createPipelineCache( const PipelineCacheCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, PipelineCache* pPipelineCache ) const
+    {
+      return static_cast<Result>( vkCreatePipelineCache( m_device, reinterpret_cast<const VkPipelineCacheCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkPipelineCache*>( pPipelineCache ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<PipelineCache>::type createPipelineCache( const PipelineCacheCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      PipelineCache pipelineCache;
+      Result result = static_cast<Result>( vkCreatePipelineCache( m_device, reinterpret_cast<const VkPipelineCacheCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkPipelineCache*>( &pipelineCache ) ) );
+      return createResultValue( result, pipelineCache, "vk::Device::createPipelineCache" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyPipelineCache( PipelineCache pipelineCache, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyPipelineCache( m_device, static_cast<VkPipelineCache>( pipelineCache ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyPipelineCache( PipelineCache pipelineCache, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyPipelineCache( m_device, static_cast<VkPipelineCache>( pipelineCache ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getPipelineCacheData( PipelineCache pipelineCache, size_t* pDataSize, void* pData ) const
+    {
+      return static_cast<Result>( vkGetPipelineCacheData( m_device, static_cast<VkPipelineCache>( pipelineCache ), pDataSize, pData ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<uint8_t>>
+    typename ResultValueType<std::vector<uint8_t,Allocator>>::type getPipelineCacheData( PipelineCache pipelineCache ) const
+    {
+      std::vector<uint8_t,Allocator> data;
+      size_t dataSize;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkGetPipelineCacheData( m_device, static_cast<VkPipelineCache>( pipelineCache ), &dataSize, nullptr ) );
+        if ( ( result == Result::eSuccess ) && dataSize )
+        {
+          data.resize( dataSize );
+          result = static_cast<Result>( vkGetPipelineCacheData( m_device, static_cast<VkPipelineCache>( pipelineCache ), &dataSize, reinterpret_cast<void*>( data.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( dataSize <= data.size() ); 
+      data.resize( dataSize ); 
+      return createResultValue( result, data, "vk::Device::getPipelineCacheData" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result mergePipelineCaches( PipelineCache dstCache, uint32_t srcCacheCount, const PipelineCache* pSrcCaches ) const
+    {
+      return static_cast<Result>( vkMergePipelineCaches( m_device, static_cast<VkPipelineCache>( dstCache ), srcCacheCount, reinterpret_cast<const VkPipelineCache*>( pSrcCaches ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type mergePipelineCaches( PipelineCache dstCache, ArrayProxy<const PipelineCache> srcCaches ) const
+    {
+      Result result = static_cast<Result>( vkMergePipelineCaches( m_device, static_cast<VkPipelineCache>( dstCache ), srcCaches.size() , reinterpret_cast<const VkPipelineCache*>( srcCaches.data() ) ) );
+      return createResultValue( result, "vk::Device::mergePipelineCaches" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createGraphicsPipelines( PipelineCache pipelineCache, uint32_t createInfoCount, const GraphicsPipelineCreateInfo* pCreateInfos, const AllocationCallbacks* pAllocator, Pipeline* pPipelines ) const
+    {
+      return static_cast<Result>( vkCreateGraphicsPipelines( m_device, static_cast<VkPipelineCache>( pipelineCache ), createInfoCount, reinterpret_cast<const VkGraphicsPipelineCreateInfo*>( pCreateInfos ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkPipeline*>( pPipelines ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<Pipeline>>
+    typename ResultValueType<std::vector<Pipeline,Allocator>>::type createGraphicsPipelines( PipelineCache pipelineCache, ArrayProxy<const GraphicsPipelineCreateInfo> createInfos, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      std::vector<Pipeline,Allocator> pipelines( createInfos.size() );
+      Result result = static_cast<Result>( vkCreateGraphicsPipelines( m_device, static_cast<VkPipelineCache>( pipelineCache ), createInfos.size() , reinterpret_cast<const VkGraphicsPipelineCreateInfo*>( createInfos.data() ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkPipeline*>( pipelines.data() ) ) );
+      return createResultValue( result, pipelines, "vk::Device::createGraphicsPipelines" );
+    }
+
+    ResultValueType<Pipeline>::type createGraphicsPipeline( PipelineCache pipelineCache, const GraphicsPipelineCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Pipeline pipeline;
+      Result result = static_cast<Result>( vkCreateGraphicsPipelines( m_device, static_cast<VkPipelineCache>( pipelineCache ), 1 , reinterpret_cast<const VkGraphicsPipelineCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkPipeline*>( &pipeline ) ) );
+      return createResultValue( result, pipeline, "vk::Device::createGraphicsPipeline" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createComputePipelines( PipelineCache pipelineCache, uint32_t createInfoCount, const ComputePipelineCreateInfo* pCreateInfos, const AllocationCallbacks* pAllocator, Pipeline* pPipelines ) const
+    {
+      return static_cast<Result>( vkCreateComputePipelines( m_device, static_cast<VkPipelineCache>( pipelineCache ), createInfoCount, reinterpret_cast<const VkComputePipelineCreateInfo*>( pCreateInfos ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkPipeline*>( pPipelines ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<Pipeline>>
+    typename ResultValueType<std::vector<Pipeline,Allocator>>::type createComputePipelines( PipelineCache pipelineCache, ArrayProxy<const ComputePipelineCreateInfo> createInfos, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      std::vector<Pipeline,Allocator> pipelines( createInfos.size() );
+      Result result = static_cast<Result>( vkCreateComputePipelines( m_device, static_cast<VkPipelineCache>( pipelineCache ), createInfos.size() , reinterpret_cast<const VkComputePipelineCreateInfo*>( createInfos.data() ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkPipeline*>( pipelines.data() ) ) );
+      return createResultValue( result, pipelines, "vk::Device::createComputePipelines" );
+    }
+
+    ResultValueType<Pipeline>::type createComputePipeline( PipelineCache pipelineCache, const ComputePipelineCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Pipeline pipeline;
+      Result result = static_cast<Result>( vkCreateComputePipelines( m_device, static_cast<VkPipelineCache>( pipelineCache ), 1 , reinterpret_cast<const VkComputePipelineCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkPipeline*>( &pipeline ) ) );
+      return createResultValue( result, pipeline, "vk::Device::createComputePipeline" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyPipeline( Pipeline pipeline, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyPipeline( m_device, static_cast<VkPipeline>( pipeline ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyPipeline( Pipeline pipeline, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyPipeline( m_device, static_cast<VkPipeline>( pipeline ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createPipelineLayout( const PipelineLayoutCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, PipelineLayout* pPipelineLayout ) const
+    {
+      return static_cast<Result>( vkCreatePipelineLayout( m_device, reinterpret_cast<const VkPipelineLayoutCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkPipelineLayout*>( pPipelineLayout ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<PipelineLayout>::type createPipelineLayout( const PipelineLayoutCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      PipelineLayout pipelineLayout;
+      Result result = static_cast<Result>( vkCreatePipelineLayout( m_device, reinterpret_cast<const VkPipelineLayoutCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkPipelineLayout*>( &pipelineLayout ) ) );
+      return createResultValue( result, pipelineLayout, "vk::Device::createPipelineLayout" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyPipelineLayout( PipelineLayout pipelineLayout, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyPipelineLayout( m_device, static_cast<VkPipelineLayout>( pipelineLayout ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyPipelineLayout( PipelineLayout pipelineLayout, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyPipelineLayout( m_device, static_cast<VkPipelineLayout>( pipelineLayout ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createSampler( const SamplerCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Sampler* pSampler ) const
+    {
+      return static_cast<Result>( vkCreateSampler( m_device, reinterpret_cast<const VkSamplerCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSampler*>( pSampler ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Sampler>::type createSampler( const SamplerCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Sampler sampler;
+      Result result = static_cast<Result>( vkCreateSampler( m_device, reinterpret_cast<const VkSamplerCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSampler*>( &sampler ) ) );
+      return createResultValue( result, sampler, "vk::Device::createSampler" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroySampler( Sampler sampler, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroySampler( m_device, static_cast<VkSampler>( sampler ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroySampler( Sampler sampler, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroySampler( m_device, static_cast<VkSampler>( sampler ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createDescriptorSetLayout( const DescriptorSetLayoutCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, DescriptorSetLayout* pSetLayout ) const
+    {
+      return static_cast<Result>( vkCreateDescriptorSetLayout( m_device, reinterpret_cast<const VkDescriptorSetLayoutCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkDescriptorSetLayout*>( pSetLayout ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<DescriptorSetLayout>::type createDescriptorSetLayout( const DescriptorSetLayoutCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      DescriptorSetLayout setLayout;
+      Result result = static_cast<Result>( vkCreateDescriptorSetLayout( m_device, reinterpret_cast<const VkDescriptorSetLayoutCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkDescriptorSetLayout*>( &setLayout ) ) );
+      return createResultValue( result, setLayout, "vk::Device::createDescriptorSetLayout" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyDescriptorSetLayout( DescriptorSetLayout descriptorSetLayout, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyDescriptorSetLayout( m_device, static_cast<VkDescriptorSetLayout>( descriptorSetLayout ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyDescriptorSetLayout( DescriptorSetLayout descriptorSetLayout, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyDescriptorSetLayout( m_device, static_cast<VkDescriptorSetLayout>( descriptorSetLayout ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createDescriptorPool( const DescriptorPoolCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, DescriptorPool* pDescriptorPool ) const
+    {
+      return static_cast<Result>( vkCreateDescriptorPool( m_device, reinterpret_cast<const VkDescriptorPoolCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkDescriptorPool*>( pDescriptorPool ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<DescriptorPool>::type createDescriptorPool( const DescriptorPoolCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      DescriptorPool descriptorPool;
+      Result result = static_cast<Result>( vkCreateDescriptorPool( m_device, reinterpret_cast<const VkDescriptorPoolCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkDescriptorPool*>( &descriptorPool ) ) );
+      return createResultValue( result, descriptorPool, "vk::Device::createDescriptorPool" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyDescriptorPool( DescriptorPool descriptorPool, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyDescriptorPool( m_device, static_cast<VkDescriptorPool>( descriptorPool ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyDescriptorPool( DescriptorPool descriptorPool, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyDescriptorPool( m_device, static_cast<VkDescriptorPool>( descriptorPool ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result resetDescriptorPool( DescriptorPool descriptorPool, DescriptorPoolResetFlags flags ) const
+    {
+      return static_cast<Result>( vkResetDescriptorPool( m_device, static_cast<VkDescriptorPool>( descriptorPool ), static_cast<VkDescriptorPoolResetFlags>( flags ) ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type resetDescriptorPool( DescriptorPool descriptorPool, DescriptorPoolResetFlags flags = DescriptorPoolResetFlags() ) const
+    {
+      Result result = static_cast<Result>( vkResetDescriptorPool( m_device, static_cast<VkDescriptorPool>( descriptorPool ), static_cast<VkDescriptorPoolResetFlags>( flags ) ) );
+      return createResultValue( result, "vk::Device::resetDescriptorPool" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result allocateDescriptorSets( const DescriptorSetAllocateInfo* pAllocateInfo, DescriptorSet* pDescriptorSets ) const
+    {
+      return static_cast<Result>( vkAllocateDescriptorSets( m_device, reinterpret_cast<const VkDescriptorSetAllocateInfo*>( pAllocateInfo ), reinterpret_cast<VkDescriptorSet*>( pDescriptorSets ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<DescriptorSet>>
+    typename ResultValueType<std::vector<DescriptorSet,Allocator>>::type allocateDescriptorSets( const DescriptorSetAllocateInfo & allocateInfo ) const
+    {
+      std::vector<DescriptorSet,Allocator> descriptorSets( allocateInfo.descriptorSetCount );
+      Result result = static_cast<Result>( vkAllocateDescriptorSets( m_device, reinterpret_cast<const VkDescriptorSetAllocateInfo*>( &allocateInfo ), reinterpret_cast<VkDescriptorSet*>( descriptorSets.data() ) ) );
+      return createResultValue( result, descriptorSets, "vk::Device::allocateDescriptorSets" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result freeDescriptorSets( DescriptorPool descriptorPool, uint32_t descriptorSetCount, const DescriptorSet* pDescriptorSets ) const
+    {
+      return static_cast<Result>( vkFreeDescriptorSets( m_device, static_cast<VkDescriptorPool>( descriptorPool ), descriptorSetCount, reinterpret_cast<const VkDescriptorSet*>( pDescriptorSets ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type freeDescriptorSets( DescriptorPool descriptorPool, ArrayProxy<const DescriptorSet> descriptorSets ) const
+    {
+      Result result = static_cast<Result>( vkFreeDescriptorSets( m_device, static_cast<VkDescriptorPool>( descriptorPool ), descriptorSets.size() , reinterpret_cast<const VkDescriptorSet*>( descriptorSets.data() ) ) );
+      return createResultValue( result, "vk::Device::freeDescriptorSets" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void updateDescriptorSets( uint32_t descriptorWriteCount, const WriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const CopyDescriptorSet* pDescriptorCopies ) const
+    {
+      vkUpdateDescriptorSets( m_device, descriptorWriteCount, reinterpret_cast<const VkWriteDescriptorSet*>( pDescriptorWrites ), descriptorCopyCount, reinterpret_cast<const VkCopyDescriptorSet*>( pDescriptorCopies ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void updateDescriptorSets( ArrayProxy<const WriteDescriptorSet> descriptorWrites, ArrayProxy<const CopyDescriptorSet> descriptorCopies ) const
+    {
+      vkUpdateDescriptorSets( m_device, descriptorWrites.size() , reinterpret_cast<const VkWriteDescriptorSet*>( descriptorWrites.data() ), descriptorCopies.size() , reinterpret_cast<const VkCopyDescriptorSet*>( descriptorCopies.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createFramebuffer( const FramebufferCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Framebuffer* pFramebuffer ) const
+    {
+      return static_cast<Result>( vkCreateFramebuffer( m_device, reinterpret_cast<const VkFramebufferCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkFramebuffer*>( pFramebuffer ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Framebuffer>::type createFramebuffer( const FramebufferCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Framebuffer framebuffer;
+      Result result = static_cast<Result>( vkCreateFramebuffer( m_device, reinterpret_cast<const VkFramebufferCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkFramebuffer*>( &framebuffer ) ) );
+      return createResultValue( result, framebuffer, "vk::Device::createFramebuffer" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyFramebuffer( Framebuffer framebuffer, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyFramebuffer( m_device, static_cast<VkFramebuffer>( framebuffer ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyFramebuffer( Framebuffer framebuffer, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyFramebuffer( m_device, static_cast<VkFramebuffer>( framebuffer ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createRenderPass( const RenderPassCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, RenderPass* pRenderPass ) const
+    {
+      return static_cast<Result>( vkCreateRenderPass( m_device, reinterpret_cast<const VkRenderPassCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkRenderPass*>( pRenderPass ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<RenderPass>::type createRenderPass( const RenderPassCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      RenderPass renderPass;
+      Result result = static_cast<Result>( vkCreateRenderPass( m_device, reinterpret_cast<const VkRenderPassCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkRenderPass*>( &renderPass ) ) );
+      return createResultValue( result, renderPass, "vk::Device::createRenderPass" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyRenderPass( RenderPass renderPass, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyRenderPass( m_device, static_cast<VkRenderPass>( renderPass ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyRenderPass( RenderPass renderPass, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyRenderPass( m_device, static_cast<VkRenderPass>( renderPass ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getRenderAreaGranularity( RenderPass renderPass, Extent2D* pGranularity ) const
+    {
+      vkGetRenderAreaGranularity( m_device, static_cast<VkRenderPass>( renderPass ), reinterpret_cast<VkExtent2D*>( pGranularity ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Extent2D getRenderAreaGranularity( RenderPass renderPass ) const
+    {
+      Extent2D granularity;
+      vkGetRenderAreaGranularity( m_device, static_cast<VkRenderPass>( renderPass ), reinterpret_cast<VkExtent2D*>( &granularity ) );
+      return granularity;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createCommandPool( const CommandPoolCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, CommandPool* pCommandPool ) const
+    {
+      return static_cast<Result>( vkCreateCommandPool( m_device, reinterpret_cast<const VkCommandPoolCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkCommandPool*>( pCommandPool ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<CommandPool>::type createCommandPool( const CommandPoolCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      CommandPool commandPool;
+      Result result = static_cast<Result>( vkCreateCommandPool( m_device, reinterpret_cast<const VkCommandPoolCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkCommandPool*>( &commandPool ) ) );
+      return createResultValue( result, commandPool, "vk::Device::createCommandPool" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyCommandPool( CommandPool commandPool, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyCommandPool( m_device, static_cast<VkCommandPool>( commandPool ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyCommandPool( CommandPool commandPool, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyCommandPool( m_device, static_cast<VkCommandPool>( commandPool ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    Result resetCommandPool( CommandPool commandPool, CommandPoolResetFlags flags ) const
+    {
+      return static_cast<Result>( vkResetCommandPool( m_device, static_cast<VkCommandPool>( commandPool ), static_cast<VkCommandPoolResetFlags>( flags ) ) );
+    }
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<void>::type resetCommandPool( CommandPool commandPool, CommandPoolResetFlags flags ) const
+    {
+      Result result = static_cast<Result>( vkResetCommandPool( m_device, static_cast<VkCommandPool>( commandPool ), static_cast<VkCommandPoolResetFlags>( flags ) ) );
+      return createResultValue( result, "vk::Device::resetCommandPool" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result allocateCommandBuffers( const CommandBufferAllocateInfo* pAllocateInfo, CommandBuffer* pCommandBuffers ) const
+    {
+      return static_cast<Result>( vkAllocateCommandBuffers( m_device, reinterpret_cast<const VkCommandBufferAllocateInfo*>( pAllocateInfo ), reinterpret_cast<VkCommandBuffer*>( pCommandBuffers ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<CommandBuffer>>
+    typename ResultValueType<std::vector<CommandBuffer,Allocator>>::type allocateCommandBuffers( const CommandBufferAllocateInfo & allocateInfo ) const
+    {
+      std::vector<CommandBuffer,Allocator> commandBuffers( allocateInfo.commandBufferCount );
+      Result result = static_cast<Result>( vkAllocateCommandBuffers( m_device, reinterpret_cast<const VkCommandBufferAllocateInfo*>( &allocateInfo ), reinterpret_cast<VkCommandBuffer*>( commandBuffers.data() ) ) );
+      return createResultValue( result, commandBuffers, "vk::Device::allocateCommandBuffers" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void freeCommandBuffers( CommandPool commandPool, uint32_t commandBufferCount, const CommandBuffer* pCommandBuffers ) const
+    {
+      vkFreeCommandBuffers( m_device, static_cast<VkCommandPool>( commandPool ), commandBufferCount, reinterpret_cast<const VkCommandBuffer*>( pCommandBuffers ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void freeCommandBuffers( CommandPool commandPool, ArrayProxy<const CommandBuffer> commandBuffers ) const
+    {
+      vkFreeCommandBuffers( m_device, static_cast<VkCommandPool>( commandPool ), commandBuffers.size() , reinterpret_cast<const VkCommandBuffer*>( commandBuffers.data() ) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createSharedSwapchainsKHR( uint32_t swapchainCount, const SwapchainCreateInfoKHR* pCreateInfos, const AllocationCallbacks* pAllocator, SwapchainKHR* pSwapchains ) const
+    {
+      return static_cast<Result>( vkCreateSharedSwapchainsKHR( m_device, swapchainCount, reinterpret_cast<const VkSwapchainCreateInfoKHR*>( pCreateInfos ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSwapchainKHR*>( pSwapchains ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<SwapchainKHR>>
+    typename ResultValueType<std::vector<SwapchainKHR,Allocator>>::type createSharedSwapchainsKHR( ArrayProxy<const SwapchainCreateInfoKHR> createInfos, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      std::vector<SwapchainKHR,Allocator> swapchains( createInfos.size() );
+      Result result = static_cast<Result>( vkCreateSharedSwapchainsKHR( m_device, createInfos.size() , reinterpret_cast<const VkSwapchainCreateInfoKHR*>( createInfos.data() ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSwapchainKHR*>( swapchains.data() ) ) );
+      return createResultValue( result, swapchains, "vk::Device::createSharedSwapchainsKHR" );
+    }
+
+    ResultValueType<SwapchainKHR>::type createSharedSwapchainKHR( const SwapchainCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SwapchainKHR swapchain;
+      Result result = static_cast<Result>( vkCreateSharedSwapchainsKHR( m_device, 1 , reinterpret_cast<const VkSwapchainCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSwapchainKHR*>( &swapchain ) ) );
+      return createResultValue( result, swapchain, "vk::Device::createSharedSwapchainKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createSwapchainKHR( const SwapchainCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, SwapchainKHR* pSwapchain ) const
+    {
+      return static_cast<Result>( vkCreateSwapchainKHR( m_device, reinterpret_cast<const VkSwapchainCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSwapchainKHR*>( pSwapchain ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<SwapchainKHR>::type createSwapchainKHR( const SwapchainCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SwapchainKHR swapchain;
+      Result result = static_cast<Result>( vkCreateSwapchainKHR( m_device, reinterpret_cast<const VkSwapchainCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSwapchainKHR*>( &swapchain ) ) );
+      return createResultValue( result, swapchain, "vk::Device::createSwapchainKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroySwapchainKHR( SwapchainKHR swapchain, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroySwapchainKHR( m_device, static_cast<VkSwapchainKHR>( swapchain ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroySwapchainKHR( SwapchainKHR swapchain, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroySwapchainKHR( m_device, static_cast<VkSwapchainKHR>( swapchain ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getSwapchainImagesKHR( SwapchainKHR swapchain, uint32_t* pSwapchainImageCount, Image* pSwapchainImages ) const
+    {
+      return static_cast<Result>( vkGetSwapchainImagesKHR( m_device, static_cast<VkSwapchainKHR>( swapchain ), pSwapchainImageCount, reinterpret_cast<VkImage*>( pSwapchainImages ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<Image>>
+    typename ResultValueType<std::vector<Image,Allocator>>::type getSwapchainImagesKHR( SwapchainKHR swapchain ) const
+    {
+      std::vector<Image,Allocator> swapchainImages;
+      uint32_t swapchainImageCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkGetSwapchainImagesKHR( m_device, static_cast<VkSwapchainKHR>( swapchain ), &swapchainImageCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && swapchainImageCount )
+        {
+          swapchainImages.resize( swapchainImageCount );
+          result = static_cast<Result>( vkGetSwapchainImagesKHR( m_device, static_cast<VkSwapchainKHR>( swapchain ), &swapchainImageCount, reinterpret_cast<VkImage*>( swapchainImages.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( swapchainImageCount <= swapchainImages.size() ); 
+      swapchainImages.resize( swapchainImageCount ); 
+      return createResultValue( result, swapchainImages, "vk::Device::getSwapchainImagesKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result acquireNextImageKHR( SwapchainKHR swapchain, uint64_t timeout, Semaphore semaphore, Fence fence, uint32_t* pImageIndex ) const
+    {
+      return static_cast<Result>( vkAcquireNextImageKHR( m_device, static_cast<VkSwapchainKHR>( swapchain ), timeout, static_cast<VkSemaphore>( semaphore ), static_cast<VkFence>( fence ), pImageIndex ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValue<uint32_t> acquireNextImageKHR( SwapchainKHR swapchain, uint64_t timeout, Semaphore semaphore, Fence fence ) const
+    {
+      uint32_t imageIndex;
+      Result result = static_cast<Result>( vkAcquireNextImageKHR( m_device, static_cast<VkSwapchainKHR>( swapchain ), timeout, static_cast<VkSemaphore>( semaphore ), static_cast<VkFence>( fence ), &imageIndex ) );
+      return createResultValue( result, imageIndex, "vk::Device::acquireNextImageKHR", { Result::eSuccess, Result::eTimeout, Result::eNotReady, Result::eSuboptimalKHR } );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result debugMarkerSetObjectNameEXT( DebugMarkerObjectNameInfoEXT* pNameInfo ) const
+    {
+      return static_cast<Result>( vkDebugMarkerSetObjectNameEXT( m_device, reinterpret_cast<VkDebugMarkerObjectNameInfoEXT*>( pNameInfo ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<DebugMarkerObjectNameInfoEXT>::type debugMarkerSetObjectNameEXT() const
+    {
+      DebugMarkerObjectNameInfoEXT nameInfo;
+      Result result = static_cast<Result>( vkDebugMarkerSetObjectNameEXT( m_device, reinterpret_cast<VkDebugMarkerObjectNameInfoEXT*>( &nameInfo ) ) );
+      return createResultValue( result, nameInfo, "vk::Device::debugMarkerSetObjectNameEXT" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result debugMarkerSetObjectTagEXT( DebugMarkerObjectTagInfoEXT* pTagInfo ) const
+    {
+      return static_cast<Result>( vkDebugMarkerSetObjectTagEXT( m_device, reinterpret_cast<VkDebugMarkerObjectTagInfoEXT*>( pTagInfo ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<DebugMarkerObjectTagInfoEXT>::type debugMarkerSetObjectTagEXT() const
+    {
+      DebugMarkerObjectTagInfoEXT tagInfo;
+      Result result = static_cast<Result>( vkDebugMarkerSetObjectTagEXT( m_device, reinterpret_cast<VkDebugMarkerObjectTagInfoEXT*>( &tagInfo ) ) );
+      return createResultValue( result, tagInfo, "vk::Device::debugMarkerSetObjectTagEXT" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkDevice() const
+    {
+      return m_device;
+    }
+
+    explicit operator bool() const
+    {
+      return m_device != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_device == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkDevice m_device;
+  };
+  static_assert( sizeof( Device ) == sizeof( VkDevice ), "handle and wrapper have different size!" );
+
+  class PhysicalDevice
+  {
+  public:
+    PhysicalDevice()
+      : m_physicalDevice(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    PhysicalDevice(VkPhysicalDevice physicalDevice)
+       : m_physicalDevice(physicalDevice)
+    {}
+
+    PhysicalDevice& operator=(VkPhysicalDevice physicalDevice)
+    {
+      m_physicalDevice = physicalDevice;
+      return *this;
+    }
+#endif
+
+    void getProperties( PhysicalDeviceProperties* pProperties ) const
+    {
+      vkGetPhysicalDeviceProperties( m_physicalDevice, reinterpret_cast<VkPhysicalDeviceProperties*>( pProperties ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    PhysicalDeviceProperties getProperties() const
+    {
+      PhysicalDeviceProperties properties;
+      vkGetPhysicalDeviceProperties( m_physicalDevice, reinterpret_cast<VkPhysicalDeviceProperties*>( &properties ) );
+      return properties;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getQueueFamilyProperties( uint32_t* pQueueFamilyPropertyCount, QueueFamilyProperties* pQueueFamilyProperties ) const
+    {
+      vkGetPhysicalDeviceQueueFamilyProperties( m_physicalDevice, pQueueFamilyPropertyCount, reinterpret_cast<VkQueueFamilyProperties*>( pQueueFamilyProperties ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<QueueFamilyProperties>>
+    std::vector<QueueFamilyProperties,Allocator> getQueueFamilyProperties() const
+    {
+      std::vector<QueueFamilyProperties,Allocator> queueFamilyProperties;
+      uint32_t queueFamilyPropertyCount;
+      vkGetPhysicalDeviceQueueFamilyProperties( m_physicalDevice, &queueFamilyPropertyCount, nullptr );
+      queueFamilyProperties.resize( queueFamilyPropertyCount );
+      vkGetPhysicalDeviceQueueFamilyProperties( m_physicalDevice, &queueFamilyPropertyCount, reinterpret_cast<VkQueueFamilyProperties*>( queueFamilyProperties.data() ) );
+      return queueFamilyProperties;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getMemoryProperties( PhysicalDeviceMemoryProperties* pMemoryProperties ) const
+    {
+      vkGetPhysicalDeviceMemoryProperties( m_physicalDevice, reinterpret_cast<VkPhysicalDeviceMemoryProperties*>( pMemoryProperties ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    PhysicalDeviceMemoryProperties getMemoryProperties() const
+    {
+      PhysicalDeviceMemoryProperties memoryProperties;
+      vkGetPhysicalDeviceMemoryProperties( m_physicalDevice, reinterpret_cast<VkPhysicalDeviceMemoryProperties*>( &memoryProperties ) );
+      return memoryProperties;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getFeatures( PhysicalDeviceFeatures* pFeatures ) const
+    {
+      vkGetPhysicalDeviceFeatures( m_physicalDevice, reinterpret_cast<VkPhysicalDeviceFeatures*>( pFeatures ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    PhysicalDeviceFeatures getFeatures() const
+    {
+      PhysicalDeviceFeatures features;
+      vkGetPhysicalDeviceFeatures( m_physicalDevice, reinterpret_cast<VkPhysicalDeviceFeatures*>( &features ) );
+      return features;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getFormatProperties( Format format, FormatProperties* pFormatProperties ) const
+    {
+      vkGetPhysicalDeviceFormatProperties( m_physicalDevice, static_cast<VkFormat>( format ), reinterpret_cast<VkFormatProperties*>( pFormatProperties ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    FormatProperties getFormatProperties( Format format ) const
+    {
+      FormatProperties formatProperties;
+      vkGetPhysicalDeviceFormatProperties( m_physicalDevice, static_cast<VkFormat>( format ), reinterpret_cast<VkFormatProperties*>( &formatProperties ) );
+      return formatProperties;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getImageFormatProperties( Format format, ImageType type, ImageTiling tiling, ImageUsageFlags usage, ImageCreateFlags flags, ImageFormatProperties* pImageFormatProperties ) const
+    {
+      return static_cast<Result>( vkGetPhysicalDeviceImageFormatProperties( m_physicalDevice, static_cast<VkFormat>( format ), static_cast<VkImageType>( type ), static_cast<VkImageTiling>( tiling ), static_cast<VkImageUsageFlags>( usage ), static_cast<VkImageCreateFlags>( flags ), reinterpret_cast<VkImageFormatProperties*>( pImageFormatProperties ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<ImageFormatProperties>::type getImageFormatProperties( Format format, ImageType type, ImageTiling tiling, ImageUsageFlags usage, ImageCreateFlags flags ) const
+    {
+      ImageFormatProperties imageFormatProperties;
+      Result result = static_cast<Result>( vkGetPhysicalDeviceImageFormatProperties( m_physicalDevice, static_cast<VkFormat>( format ), static_cast<VkImageType>( type ), static_cast<VkImageTiling>( tiling ), static_cast<VkImageUsageFlags>( usage ), static_cast<VkImageCreateFlags>( flags ), reinterpret_cast<VkImageFormatProperties*>( &imageFormatProperties ) ) );
+      return createResultValue( result, imageFormatProperties, "vk::PhysicalDevice::getImageFormatProperties" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createDevice( const DeviceCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Device* pDevice ) const
+    {
+      return static_cast<Result>( vkCreateDevice( m_physicalDevice, reinterpret_cast<const VkDeviceCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkDevice*>( pDevice ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Device>::type createDevice( const DeviceCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      Device device;
+      Result result = static_cast<Result>( vkCreateDevice( m_physicalDevice, reinterpret_cast<const VkDeviceCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkDevice*>( &device ) ) );
+      return createResultValue( result, device, "vk::PhysicalDevice::createDevice" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result enumerateDeviceLayerProperties( uint32_t* pPropertyCount, LayerProperties* pProperties ) const
+    {
+      return static_cast<Result>( vkEnumerateDeviceLayerProperties( m_physicalDevice, pPropertyCount, reinterpret_cast<VkLayerProperties*>( pProperties ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<LayerProperties>>
+    typename ResultValueType<std::vector<LayerProperties,Allocator>>::type enumerateDeviceLayerProperties() const
+    {
+      std::vector<LayerProperties,Allocator> properties;
+      uint32_t propertyCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkEnumerateDeviceLayerProperties( m_physicalDevice, &propertyCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && propertyCount )
+        {
+          properties.resize( propertyCount );
+          result = static_cast<Result>( vkEnumerateDeviceLayerProperties( m_physicalDevice, &propertyCount, reinterpret_cast<VkLayerProperties*>( properties.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( propertyCount <= properties.size() ); 
+      properties.resize( propertyCount ); 
+      return createResultValue( result, properties, "vk::PhysicalDevice::enumerateDeviceLayerProperties" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result enumerateDeviceExtensionProperties( const char* pLayerName, uint32_t* pPropertyCount, ExtensionProperties* pProperties ) const
+    {
+      return static_cast<Result>( vkEnumerateDeviceExtensionProperties( m_physicalDevice, pLayerName, pPropertyCount, reinterpret_cast<VkExtensionProperties*>( pProperties ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<ExtensionProperties>>
+    typename ResultValueType<std::vector<ExtensionProperties,Allocator>>::type enumerateDeviceExtensionProperties( Optional<const std::string> layerName = nullptr ) const
+    {
+      std::vector<ExtensionProperties,Allocator> properties;
+      uint32_t propertyCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkEnumerateDeviceExtensionProperties( m_physicalDevice, layerName ? layerName->c_str() : nullptr, &propertyCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && propertyCount )
+        {
+          properties.resize( propertyCount );
+          result = static_cast<Result>( vkEnumerateDeviceExtensionProperties( m_physicalDevice, layerName ? layerName->c_str() : nullptr, &propertyCount, reinterpret_cast<VkExtensionProperties*>( properties.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( propertyCount <= properties.size() ); 
+      properties.resize( propertyCount ); 
+      return createResultValue( result, properties, "vk::PhysicalDevice::enumerateDeviceExtensionProperties" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void getSparseImageFormatProperties( Format format, ImageType type, SampleCountFlagBits samples, ImageUsageFlags usage, ImageTiling tiling, uint32_t* pPropertyCount, SparseImageFormatProperties* pProperties ) const
+    {
+      vkGetPhysicalDeviceSparseImageFormatProperties( m_physicalDevice, static_cast<VkFormat>( format ), static_cast<VkImageType>( type ), static_cast<VkSampleCountFlagBits>( samples ), static_cast<VkImageUsageFlags>( usage ), static_cast<VkImageTiling>( tiling ), pPropertyCount, reinterpret_cast<VkSparseImageFormatProperties*>( pProperties ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<SparseImageFormatProperties>>
+    std::vector<SparseImageFormatProperties,Allocator> getSparseImageFormatProperties( Format format, ImageType type, SampleCountFlagBits samples, ImageUsageFlags usage, ImageTiling tiling ) const
+    {
+      std::vector<SparseImageFormatProperties,Allocator> properties;
+      uint32_t propertyCount;
+      vkGetPhysicalDeviceSparseImageFormatProperties( m_physicalDevice, static_cast<VkFormat>( format ), static_cast<VkImageType>( type ), static_cast<VkSampleCountFlagBits>( samples ), static_cast<VkImageUsageFlags>( usage ), static_cast<VkImageTiling>( tiling ), &propertyCount, nullptr );
+      properties.resize( propertyCount );
+      vkGetPhysicalDeviceSparseImageFormatProperties( m_physicalDevice, static_cast<VkFormat>( format ), static_cast<VkImageType>( type ), static_cast<VkSampleCountFlagBits>( samples ), static_cast<VkImageUsageFlags>( usage ), static_cast<VkImageTiling>( tiling ), &propertyCount, reinterpret_cast<VkSparseImageFormatProperties*>( properties.data() ) );
+      return properties;
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getDisplayPropertiesKHR( uint32_t* pPropertyCount, DisplayPropertiesKHR* pProperties ) const
+    {
+      return static_cast<Result>( vkGetPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, pPropertyCount, reinterpret_cast<VkDisplayPropertiesKHR*>( pProperties ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<DisplayPropertiesKHR>>
+    typename ResultValueType<std::vector<DisplayPropertiesKHR,Allocator>>::type getDisplayPropertiesKHR() const
+    {
+      std::vector<DisplayPropertiesKHR,Allocator> properties;
+      uint32_t propertyCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkGetPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, &propertyCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && propertyCount )
+        {
+          properties.resize( propertyCount );
+          result = static_cast<Result>( vkGetPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, &propertyCount, reinterpret_cast<VkDisplayPropertiesKHR*>( properties.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( propertyCount <= properties.size() ); 
+      properties.resize( propertyCount ); 
+      return createResultValue( result, properties, "vk::PhysicalDevice::getDisplayPropertiesKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getDisplayPlanePropertiesKHR( uint32_t* pPropertyCount, DisplayPlanePropertiesKHR* pProperties ) const
+    {
+      return static_cast<Result>( vkGetPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, pPropertyCount, reinterpret_cast<VkDisplayPlanePropertiesKHR*>( pProperties ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<DisplayPlanePropertiesKHR>>
+    typename ResultValueType<std::vector<DisplayPlanePropertiesKHR,Allocator>>::type getDisplayPlanePropertiesKHR() const
+    {
+      std::vector<DisplayPlanePropertiesKHR,Allocator> properties;
+      uint32_t propertyCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkGetPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, &propertyCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && propertyCount )
+        {
+          properties.resize( propertyCount );
+          result = static_cast<Result>( vkGetPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, &propertyCount, reinterpret_cast<VkDisplayPlanePropertiesKHR*>( properties.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( propertyCount <= properties.size() ); 
+      properties.resize( propertyCount ); 
+      return createResultValue( result, properties, "vk::PhysicalDevice::getDisplayPlanePropertiesKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getDisplayPlaneSupportedDisplaysKHR( uint32_t planeIndex, uint32_t* pDisplayCount, DisplayKHR* pDisplays ) const
+    {
+      return static_cast<Result>( vkGetDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, planeIndex, pDisplayCount, reinterpret_cast<VkDisplayKHR*>( pDisplays ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<DisplayKHR>>
+    typename ResultValueType<std::vector<DisplayKHR,Allocator>>::type getDisplayPlaneSupportedDisplaysKHR( uint32_t planeIndex ) const
+    {
+      std::vector<DisplayKHR,Allocator> displays;
+      uint32_t displayCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkGetDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, planeIndex, &displayCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && displayCount )
+        {
+          displays.resize( displayCount );
+          result = static_cast<Result>( vkGetDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, planeIndex, &displayCount, reinterpret_cast<VkDisplayKHR*>( displays.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( displayCount <= displays.size() ); 
+      displays.resize( displayCount ); 
+      return createResultValue( result, displays, "vk::PhysicalDevice::getDisplayPlaneSupportedDisplaysKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getDisplayModePropertiesKHR( DisplayKHR display, uint32_t* pPropertyCount, DisplayModePropertiesKHR* pProperties ) const
+    {
+      return static_cast<Result>( vkGetDisplayModePropertiesKHR( m_physicalDevice, static_cast<VkDisplayKHR>( display ), pPropertyCount, reinterpret_cast<VkDisplayModePropertiesKHR*>( pProperties ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<DisplayModePropertiesKHR>>
+    typename ResultValueType<std::vector<DisplayModePropertiesKHR,Allocator>>::type getDisplayModePropertiesKHR( DisplayKHR display ) const
+    {
+      std::vector<DisplayModePropertiesKHR,Allocator> properties;
+      uint32_t propertyCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkGetDisplayModePropertiesKHR( m_physicalDevice, static_cast<VkDisplayKHR>( display ), &propertyCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && propertyCount )
+        {
+          properties.resize( propertyCount );
+          result = static_cast<Result>( vkGetDisplayModePropertiesKHR( m_physicalDevice, static_cast<VkDisplayKHR>( display ), &propertyCount, reinterpret_cast<VkDisplayModePropertiesKHR*>( properties.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( propertyCount <= properties.size() ); 
+      properties.resize( propertyCount ); 
+      return createResultValue( result, properties, "vk::PhysicalDevice::getDisplayModePropertiesKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createDisplayModeKHR( DisplayKHR display, const DisplayModeCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, DisplayModeKHR* pMode ) const
+    {
+      return static_cast<Result>( vkCreateDisplayModeKHR( m_physicalDevice, static_cast<VkDisplayKHR>( display ), reinterpret_cast<const VkDisplayModeCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkDisplayModeKHR*>( pMode ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<DisplayModeKHR>::type createDisplayModeKHR( DisplayKHR display, const DisplayModeCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      DisplayModeKHR mode;
+      Result result = static_cast<Result>( vkCreateDisplayModeKHR( m_physicalDevice, static_cast<VkDisplayKHR>( display ), reinterpret_cast<const VkDisplayModeCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkDisplayModeKHR*>( &mode ) ) );
+      return createResultValue( result, mode, "vk::PhysicalDevice::createDisplayModeKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getDisplayPlaneCapabilitiesKHR( DisplayModeKHR mode, uint32_t planeIndex, DisplayPlaneCapabilitiesKHR* pCapabilities ) const
+    {
+      return static_cast<Result>( vkGetDisplayPlaneCapabilitiesKHR( m_physicalDevice, static_cast<VkDisplayModeKHR>( mode ), planeIndex, reinterpret_cast<VkDisplayPlaneCapabilitiesKHR*>( pCapabilities ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<DisplayPlaneCapabilitiesKHR>::type getDisplayPlaneCapabilitiesKHR( DisplayModeKHR mode, uint32_t planeIndex ) const
+    {
+      DisplayPlaneCapabilitiesKHR capabilities;
+      Result result = static_cast<Result>( vkGetDisplayPlaneCapabilitiesKHR( m_physicalDevice, static_cast<VkDisplayModeKHR>( mode ), planeIndex, reinterpret_cast<VkDisplayPlaneCapabilitiesKHR*>( &capabilities ) ) );
+      return createResultValue( result, capabilities, "vk::PhysicalDevice::getDisplayPlaneCapabilitiesKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    Bool32 getMirPresentationSupportKHR( uint32_t queueFamilyIndex, MirConnection* connection ) const
+    {
+      return vkGetPhysicalDeviceMirPresentationSupportKHR( m_physicalDevice, queueFamilyIndex, connection );
+    }
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    Bool32 getMirPresentationSupportKHR( uint32_t queueFamilyIndex, MirConnection & connection ) const
+    {
+      return vkGetPhysicalDeviceMirPresentationSupportKHR( m_physicalDevice, queueFamilyIndex, &connection );
+    }
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getSurfaceSupportKHR( uint32_t queueFamilyIndex, SurfaceKHR surface, Bool32* pSupported ) const
+    {
+      return static_cast<Result>( vkGetPhysicalDeviceSurfaceSupportKHR( m_physicalDevice, queueFamilyIndex, static_cast<VkSurfaceKHR>( surface ), pSupported ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<Bool32>::type getSurfaceSupportKHR( uint32_t queueFamilyIndex, SurfaceKHR surface ) const
+    {
+      Bool32 supported;
+      Result result = static_cast<Result>( vkGetPhysicalDeviceSurfaceSupportKHR( m_physicalDevice, queueFamilyIndex, static_cast<VkSurfaceKHR>( surface ), &supported ) );
+      return createResultValue( result, supported, "vk::PhysicalDevice::getSurfaceSupportKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getSurfaceCapabilitiesKHR( SurfaceKHR surface, SurfaceCapabilitiesKHR* pSurfaceCapabilities ) const
+    {
+      return static_cast<Result>( vkGetPhysicalDeviceSurfaceCapabilitiesKHR( m_physicalDevice, static_cast<VkSurfaceKHR>( surface ), reinterpret_cast<VkSurfaceCapabilitiesKHR*>( pSurfaceCapabilities ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<SurfaceCapabilitiesKHR>::type getSurfaceCapabilitiesKHR( SurfaceKHR surface ) const
+    {
+      SurfaceCapabilitiesKHR surfaceCapabilities;
+      Result result = static_cast<Result>( vkGetPhysicalDeviceSurfaceCapabilitiesKHR( m_physicalDevice, static_cast<VkSurfaceKHR>( surface ), reinterpret_cast<VkSurfaceCapabilitiesKHR*>( &surfaceCapabilities ) ) );
+      return createResultValue( result, surfaceCapabilities, "vk::PhysicalDevice::getSurfaceCapabilitiesKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getSurfaceFormatsKHR( SurfaceKHR surface, uint32_t* pSurfaceFormatCount, SurfaceFormatKHR* pSurfaceFormats ) const
+    {
+      return static_cast<Result>( vkGetPhysicalDeviceSurfaceFormatsKHR( m_physicalDevice, static_cast<VkSurfaceKHR>( surface ), pSurfaceFormatCount, reinterpret_cast<VkSurfaceFormatKHR*>( pSurfaceFormats ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<SurfaceFormatKHR>>
+    typename ResultValueType<std::vector<SurfaceFormatKHR,Allocator>>::type getSurfaceFormatsKHR( SurfaceKHR surface ) const
+    {
+      std::vector<SurfaceFormatKHR,Allocator> surfaceFormats;
+      uint32_t surfaceFormatCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkGetPhysicalDeviceSurfaceFormatsKHR( m_physicalDevice, static_cast<VkSurfaceKHR>( surface ), &surfaceFormatCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && surfaceFormatCount )
+        {
+          surfaceFormats.resize( surfaceFormatCount );
+          result = static_cast<Result>( vkGetPhysicalDeviceSurfaceFormatsKHR( m_physicalDevice, static_cast<VkSurfaceKHR>( surface ), &surfaceFormatCount, reinterpret_cast<VkSurfaceFormatKHR*>( surfaceFormats.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( surfaceFormatCount <= surfaceFormats.size() ); 
+      surfaceFormats.resize( surfaceFormatCount ); 
+      return createResultValue( result, surfaceFormats, "vk::PhysicalDevice::getSurfaceFormatsKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result getSurfacePresentModesKHR( SurfaceKHR surface, uint32_t* pPresentModeCount, PresentModeKHR* pPresentModes ) const
+    {
+      return static_cast<Result>( vkGetPhysicalDeviceSurfacePresentModesKHR( m_physicalDevice, static_cast<VkSurfaceKHR>( surface ), pPresentModeCount, reinterpret_cast<VkPresentModeKHR*>( pPresentModes ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<PresentModeKHR>>
+    typename ResultValueType<std::vector<PresentModeKHR,Allocator>>::type getSurfacePresentModesKHR( SurfaceKHR surface ) const
+    {
+      std::vector<PresentModeKHR,Allocator> presentModes;
+      uint32_t presentModeCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkGetPhysicalDeviceSurfacePresentModesKHR( m_physicalDevice, static_cast<VkSurfaceKHR>( surface ), &presentModeCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && presentModeCount )
+        {
+          presentModes.resize( presentModeCount );
+          result = static_cast<Result>( vkGetPhysicalDeviceSurfacePresentModesKHR( m_physicalDevice, static_cast<VkSurfaceKHR>( surface ), &presentModeCount, reinterpret_cast<VkPresentModeKHR*>( presentModes.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( presentModeCount <= presentModes.size() ); 
+      presentModes.resize( presentModeCount ); 
+      return createResultValue( result, presentModes, "vk::PhysicalDevice::getSurfacePresentModesKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    Bool32 getWaylandPresentationSupportKHR( uint32_t queueFamilyIndex, struct wl_display* display ) const
+    {
+      return vkGetPhysicalDeviceWaylandPresentationSupportKHR( m_physicalDevice, queueFamilyIndex, display );
+    }
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    Bool32 getWaylandPresentationSupportKHR( uint32_t queueFamilyIndex, struct wl_display & display ) const
+    {
+      return vkGetPhysicalDeviceWaylandPresentationSupportKHR( m_physicalDevice, queueFamilyIndex, &display );
+    }
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    Bool32 getWin32PresentationSupportKHR( uint32_t queueFamilyIndex ) const
+    {
+      return vkGetPhysicalDeviceWin32PresentationSupportKHR( m_physicalDevice, queueFamilyIndex );
+    }
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    Bool32 getWin32PresentationSupportKHR( uint32_t queueFamilyIndex ) const
+    {
+      return vkGetPhysicalDeviceWin32PresentationSupportKHR( m_physicalDevice, queueFamilyIndex );
+    }
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    Bool32 getXlibPresentationSupportKHR( uint32_t queueFamilyIndex, Display* dpy, VisualID visualID ) const
+    {
+      return vkGetPhysicalDeviceXlibPresentationSupportKHR( m_physicalDevice, queueFamilyIndex, dpy, visualID );
+    }
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    Bool32 getXlibPresentationSupportKHR( uint32_t queueFamilyIndex, Display & dpy, VisualID visualID ) const
+    {
+      return vkGetPhysicalDeviceXlibPresentationSupportKHR( m_physicalDevice, queueFamilyIndex, &dpy, visualID );
+    }
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    Bool32 getXcbPresentationSupportKHR( uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id ) const
+    {
+      return vkGetPhysicalDeviceXcbPresentationSupportKHR( m_physicalDevice, queueFamilyIndex, connection, visual_id );
+    }
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    Bool32 getXcbPresentationSupportKHR( uint32_t queueFamilyIndex, xcb_connection_t & connection, xcb_visualid_t visual_id ) const
+    {
+      return vkGetPhysicalDeviceXcbPresentationSupportKHR( m_physicalDevice, queueFamilyIndex, &connection, visual_id );
+    }
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkPhysicalDevice() const
+    {
+      return m_physicalDevice;
+    }
+
+    explicit operator bool() const
+    {
+      return m_physicalDevice != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_physicalDevice == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkPhysicalDevice m_physicalDevice;
+  };
+  static_assert( sizeof( PhysicalDevice ) == sizeof( VkPhysicalDevice ), "handle and wrapper have different size!" );
+
+  class Instance
+  {
+  public:
+    Instance()
+      : m_instance(VK_NULL_HANDLE)
+    {}
+
+#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    Instance(VkInstance instance)
+       : m_instance(instance)
+    {}
+
+    Instance& operator=(VkInstance instance)
+    {
+      m_instance = instance;
+      return *this;
+    }
+#endif
+
+    void destroy( const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyInstance( m_instance, reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroy( Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyInstance( m_instance, reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result enumeratePhysicalDevices( uint32_t* pPhysicalDeviceCount, PhysicalDevice* pPhysicalDevices ) const
+    {
+      return static_cast<Result>( vkEnumeratePhysicalDevices( m_instance, pPhysicalDeviceCount, reinterpret_cast<VkPhysicalDevice*>( pPhysicalDevices ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    template <typename Allocator = std::allocator<PhysicalDevice>>
+    typename ResultValueType<std::vector<PhysicalDevice,Allocator>>::type enumeratePhysicalDevices() const
+    {
+      std::vector<PhysicalDevice,Allocator> physicalDevices;
+      uint32_t physicalDeviceCount;
+      Result result;
+      do
+      {
+        result = static_cast<Result>( vkEnumeratePhysicalDevices( m_instance, &physicalDeviceCount, nullptr ) );
+        if ( ( result == Result::eSuccess ) && physicalDeviceCount )
+        {
+          physicalDevices.resize( physicalDeviceCount );
+          result = static_cast<Result>( vkEnumeratePhysicalDevices( m_instance, &physicalDeviceCount, reinterpret_cast<VkPhysicalDevice*>( physicalDevices.data() ) ) );
+        }
+      } while ( result == Result::eIncomplete );
+      assert( physicalDeviceCount <= physicalDevices.size() ); 
+      physicalDevices.resize( physicalDeviceCount ); 
+      return createResultValue( result, physicalDevices, "vk::Instance::enumeratePhysicalDevices" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    PFN_vkVoidFunction getProcAddr( const char* pName ) const
+    {
+      return vkGetInstanceProcAddr( m_instance, pName );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    PFN_vkVoidFunction getProcAddr( const std::string & name ) const
+    {
+      return vkGetInstanceProcAddr( m_instance, name.c_str() );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+    Result createAndroidSurfaceKHR( const AndroidSurfaceCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, SurfaceKHR* pSurface ) const
+    {
+      return static_cast<Result>( vkCreateAndroidSurfaceKHR( m_instance, reinterpret_cast<const VkAndroidSurfaceCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSurfaceKHR*>( pSurface ) ) );
+    }
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+    ResultValueType<SurfaceKHR>::type createAndroidSurfaceKHR( const AndroidSurfaceCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SurfaceKHR surface;
+      Result result = static_cast<Result>( vkCreateAndroidSurfaceKHR( m_instance, reinterpret_cast<const VkAndroidSurfaceCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSurfaceKHR*>( &surface ) ) );
+      return createResultValue( result, surface, "vk::Instance::createAndroidSurfaceKHR" );
+    }
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createDisplayPlaneSurfaceKHR( const DisplaySurfaceCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, SurfaceKHR* pSurface ) const
+    {
+      return static_cast<Result>( vkCreateDisplayPlaneSurfaceKHR( m_instance, reinterpret_cast<const VkDisplaySurfaceCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSurfaceKHR*>( pSurface ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<SurfaceKHR>::type createDisplayPlaneSurfaceKHR( const DisplaySurfaceCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SurfaceKHR surface;
+      Result result = static_cast<Result>( vkCreateDisplayPlaneSurfaceKHR( m_instance, reinterpret_cast<const VkDisplaySurfaceCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSurfaceKHR*>( &surface ) ) );
+      return createResultValue( result, surface, "vk::Instance::createDisplayPlaneSurfaceKHR" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    Result createMirSurfaceKHR( const MirSurfaceCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, SurfaceKHR* pSurface ) const
+    {
+      return static_cast<Result>( vkCreateMirSurfaceKHR( m_instance, reinterpret_cast<const VkMirSurfaceCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSurfaceKHR*>( pSurface ) ) );
+    }
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    ResultValueType<SurfaceKHR>::type createMirSurfaceKHR( const MirSurfaceCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SurfaceKHR surface;
+      Result result = static_cast<Result>( vkCreateMirSurfaceKHR( m_instance, reinterpret_cast<const VkMirSurfaceCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSurfaceKHR*>( &surface ) ) );
+      return createResultValue( result, surface, "vk::Instance::createMirSurfaceKHR" );
+    }
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroySurfaceKHR( SurfaceKHR surface, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroySurfaceKHR( m_instance, static_cast<VkSurfaceKHR>( surface ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroySurfaceKHR( SurfaceKHR surface, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroySurfaceKHR( m_instance, static_cast<VkSurfaceKHR>( surface ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    Result createWaylandSurfaceKHR( const WaylandSurfaceCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, SurfaceKHR* pSurface ) const
+    {
+      return static_cast<Result>( vkCreateWaylandSurfaceKHR( m_instance, reinterpret_cast<const VkWaylandSurfaceCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSurfaceKHR*>( pSurface ) ) );
+    }
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    ResultValueType<SurfaceKHR>::type createWaylandSurfaceKHR( const WaylandSurfaceCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SurfaceKHR surface;
+      Result result = static_cast<Result>( vkCreateWaylandSurfaceKHR( m_instance, reinterpret_cast<const VkWaylandSurfaceCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSurfaceKHR*>( &surface ) ) );
+      return createResultValue( result, surface, "vk::Instance::createWaylandSurfaceKHR" );
+    }
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    Result createWin32SurfaceKHR( const Win32SurfaceCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, SurfaceKHR* pSurface ) const
+    {
+      return static_cast<Result>( vkCreateWin32SurfaceKHR( m_instance, reinterpret_cast<const VkWin32SurfaceCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSurfaceKHR*>( pSurface ) ) );
+    }
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    ResultValueType<SurfaceKHR>::type createWin32SurfaceKHR( const Win32SurfaceCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SurfaceKHR surface;
+      Result result = static_cast<Result>( vkCreateWin32SurfaceKHR( m_instance, reinterpret_cast<const VkWin32SurfaceCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSurfaceKHR*>( &surface ) ) );
+      return createResultValue( result, surface, "vk::Instance::createWin32SurfaceKHR" );
+    }
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    Result createXlibSurfaceKHR( const XlibSurfaceCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, SurfaceKHR* pSurface ) const
+    {
+      return static_cast<Result>( vkCreateXlibSurfaceKHR( m_instance, reinterpret_cast<const VkXlibSurfaceCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSurfaceKHR*>( pSurface ) ) );
+    }
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    ResultValueType<SurfaceKHR>::type createXlibSurfaceKHR( const XlibSurfaceCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SurfaceKHR surface;
+      Result result = static_cast<Result>( vkCreateXlibSurfaceKHR( m_instance, reinterpret_cast<const VkXlibSurfaceCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSurfaceKHR*>( &surface ) ) );
+      return createResultValue( result, surface, "vk::Instance::createXlibSurfaceKHR" );
+    }
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    Result createXcbSurfaceKHR( const XcbSurfaceCreateInfoKHR* pCreateInfo, const AllocationCallbacks* pAllocator, SurfaceKHR* pSurface ) const
+    {
+      return static_cast<Result>( vkCreateXcbSurfaceKHR( m_instance, reinterpret_cast<const VkXcbSurfaceCreateInfoKHR*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkSurfaceKHR*>( pSurface ) ) );
+    }
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    ResultValueType<SurfaceKHR>::type createXcbSurfaceKHR( const XcbSurfaceCreateInfoKHR & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      SurfaceKHR surface;
+      Result result = static_cast<Result>( vkCreateXcbSurfaceKHR( m_instance, reinterpret_cast<const VkXcbSurfaceCreateInfoKHR*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkSurfaceKHR*>( &surface ) ) );
+      return createResultValue( result, surface, "vk::Instance::createXcbSurfaceKHR" );
+    }
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    Result createDebugReportCallbackEXT( const DebugReportCallbackCreateInfoEXT* pCreateInfo, const AllocationCallbacks* pAllocator, DebugReportCallbackEXT* pCallback ) const
+    {
+      return static_cast<Result>( vkCreateDebugReportCallbackEXT( m_instance, reinterpret_cast<const VkDebugReportCallbackCreateInfoEXT*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkDebugReportCallbackEXT*>( pCallback ) ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    ResultValueType<DebugReportCallbackEXT>::type createDebugReportCallbackEXT( const DebugReportCallbackCreateInfoEXT & createInfo, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      DebugReportCallbackEXT callback;
+      Result result = static_cast<Result>( vkCreateDebugReportCallbackEXT( m_instance, reinterpret_cast<const VkDebugReportCallbackCreateInfoEXT*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkDebugReportCallbackEXT*>( &callback ) ) );
+      return createResultValue( result, callback, "vk::Instance::createDebugReportCallbackEXT" );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void destroyDebugReportCallbackEXT( DebugReportCallbackEXT callback, const AllocationCallbacks* pAllocator ) const
+    {
+      vkDestroyDebugReportCallbackEXT( m_instance, static_cast<VkDebugReportCallbackEXT>( callback ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ) );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void destroyDebugReportCallbackEXT( DebugReportCallbackEXT callback, Optional<const AllocationCallbacks> allocator = nullptr ) const
+    {
+      vkDestroyDebugReportCallbackEXT( m_instance, static_cast<VkDebugReportCallbackEXT>( callback ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)) );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+    void debugReportMessageEXT( DebugReportFlagsEXT flags, DebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage ) const
+    {
+      vkDebugReportMessageEXT( m_instance, static_cast<VkDebugReportFlagsEXT>( flags ), static_cast<VkDebugReportObjectTypeEXT>( objectType ), object, location, messageCode, pLayerPrefix, pMessage );
+    }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+    void debugReportMessageEXT( DebugReportFlagsEXT flags, DebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const std::string & layerPrefix, const std::string & message ) const
+    {
+      vkDebugReportMessageEXT( m_instance, static_cast<VkDebugReportFlagsEXT>( flags ), static_cast<VkDebugReportObjectTypeEXT>( objectType ), object, location, messageCode, layerPrefix.c_str(), message.c_str() );
+    }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+#if !defined(VULKAN_HPP_TYPESAFE_CONVERSION)
+    explicit
+#endif
+    operator VkInstance() const
+    {
+      return m_instance;
+    }
+
+    explicit operator bool() const
+    {
+      return m_instance != VK_NULL_HANDLE;
+    }
+
+    bool operator!() const
+    {
+      return m_instance == VK_NULL_HANDLE;
+    }
+
+  private:
+    VkInstance m_instance;
+  };
+  static_assert( sizeof( Instance ) == sizeof( VkInstance ), "handle and wrapper have different size!" );
+
+  enum class DebugReportErrorEXT
+  {
+    eNone = VK_DEBUG_REPORT_ERROR_NONE_EXT,
+    eCallbackRef = VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT
+  };
+
+  enum class RasterizationOrderAMD
+  {
+    eStrict = VK_RASTERIZATION_ORDER_STRICT_AMD,
+    eRelaxed = VK_RASTERIZATION_ORDER_RELAXED_AMD
+  };
+
+  struct PipelineRasterizationStateRasterizationOrderAMD
+  {
+    PipelineRasterizationStateRasterizationOrderAMD( RasterizationOrderAMD rasterizationOrder_ = RasterizationOrderAMD::eStrict )
+      : sType( StructureType::ePipelineRasterizationStateRasterizationOrderAMD )
+      , pNext( nullptr )
+      , rasterizationOrder( rasterizationOrder_ )
+    {
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD( VkPipelineRasterizationStateRasterizationOrderAMD const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineRasterizationStateRasterizationOrderAMD) );
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD& operator=( VkPipelineRasterizationStateRasterizationOrderAMD const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineRasterizationStateRasterizationOrderAMD) );
+      return *this;
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD& setRasterizationOrder( RasterizationOrderAMD rasterizationOrder_ )
+    {
+      rasterizationOrder = rasterizationOrder_;
+      return *this;
+    }
+
+    operator const VkPipelineRasterizationStateRasterizationOrderAMD&() const
+    {
+      return *reinterpret_cast<const VkPipelineRasterizationStateRasterizationOrderAMD*>(this);
+    }
+
+    bool operator==( PipelineRasterizationStateRasterizationOrderAMD const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( rasterizationOrder == rhs.rasterizationOrder );
+    }
+
+    bool operator!=( PipelineRasterizationStateRasterizationOrderAMD const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    RasterizationOrderAMD rasterizationOrder;
+  };
+  static_assert( sizeof( PipelineRasterizationStateRasterizationOrderAMD ) == sizeof( VkPipelineRasterizationStateRasterizationOrderAMD ), "struct and wrapper have different size!" );
+
+  inline Result createInstance( const InstanceCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Instance* pInstance )
+  {
+    return static_cast<Result>( vkCreateInstance( reinterpret_cast<const VkInstanceCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkInstance*>( pInstance ) ) );
+  }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+  inline ResultValueType<Instance>::type createInstance( const InstanceCreateInfo & createInfo, Optional<const AllocationCallbacks> allocator = nullptr )
+  {
+    Instance instance;
+    Result result = static_cast<Result>( vkCreateInstance( reinterpret_cast<const VkInstanceCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator)), reinterpret_cast<VkInstance*>( &instance ) ) );
+    return createResultValue( result, instance, "vk::createInstance" );
+  }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+  inline Result enumerateInstanceLayerProperties( uint32_t* pPropertyCount, LayerProperties* pProperties )
+  {
+    return static_cast<Result>( vkEnumerateInstanceLayerProperties( pPropertyCount, reinterpret_cast<VkLayerProperties*>( pProperties ) ) );
+  }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+  template <typename Allocator = std::allocator<LayerProperties>>
+  typename ResultValueType<std::vector<LayerProperties,Allocator>>::type enumerateInstanceLayerProperties()
+  {
+    std::vector<LayerProperties,Allocator> properties;
+    uint32_t propertyCount;
+    Result result;
+    do
+    {
+      result = static_cast<Result>( vkEnumerateInstanceLayerProperties( &propertyCount, nullptr ) );
+      if ( ( result == Result::eSuccess ) && propertyCount )
+      {
+        properties.resize( propertyCount );
+        result = static_cast<Result>( vkEnumerateInstanceLayerProperties( &propertyCount, reinterpret_cast<VkLayerProperties*>( properties.data() ) ) );
+      }
+    } while ( result == Result::eIncomplete );
+    assert( propertyCount <= properties.size() ); 
+    properties.resize( propertyCount ); 
+    return createResultValue( result, properties, "vk::enumerateInstanceLayerProperties" );
+  }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+  inline Result enumerateInstanceExtensionProperties( const char* pLayerName, uint32_t* pPropertyCount, ExtensionProperties* pProperties )
+  {
+    return static_cast<Result>( vkEnumerateInstanceExtensionProperties( pLayerName, pPropertyCount, reinterpret_cast<VkExtensionProperties*>( pProperties ) ) );
+  }
+
+#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
+  template <typename Allocator = std::allocator<ExtensionProperties>>
+  typename ResultValueType<std::vector<ExtensionProperties,Allocator>>::type enumerateInstanceExtensionProperties( Optional<const std::string> layerName = nullptr )
+  {
+    std::vector<ExtensionProperties,Allocator> properties;
+    uint32_t propertyCount;
+    Result result;
+    do
+    {
+      result = static_cast<Result>( vkEnumerateInstanceExtensionProperties( layerName ? layerName->c_str() : nullptr, &propertyCount, nullptr ) );
+      if ( ( result == Result::eSuccess ) && propertyCount )
+      {
+        properties.resize( propertyCount );
+        result = static_cast<Result>( vkEnumerateInstanceExtensionProperties( layerName ? layerName->c_str() : nullptr, &propertyCount, reinterpret_cast<VkExtensionProperties*>( properties.data() ) ) );
+      }
+    } while ( result == Result::eIncomplete );
+    assert( propertyCount <= properties.size() ); 
+    properties.resize( propertyCount ); 
+    return createResultValue( result, properties, "vk::enumerateInstanceExtensionProperties" );
+  }
+#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
+
+  inline std::string to_string(FramebufferCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(FramebufferCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(QueryPoolCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(QueryPoolCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(RenderPassCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(RenderPassCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(SamplerCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(SamplerCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineLayoutCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineLayoutCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineCacheCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineCacheCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineDepthStencilStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineDepthStencilStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineDynamicStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineDynamicStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineColorBlendStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineColorBlendStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineMultisampleStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineMultisampleStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineRasterizationStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineRasterizationStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineViewportStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineViewportStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineTessellationStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineTessellationStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineInputAssemblyStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineInputAssemblyStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineVertexInputStateCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineVertexInputStateCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(PipelineShaderStageCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(PipelineShaderStageCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(DescriptorSetLayoutCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(DescriptorSetLayoutCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(BufferViewCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(BufferViewCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(InstanceCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(InstanceCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(DeviceCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(DeviceCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(DeviceQueueCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(DeviceQueueCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(ImageViewCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(ImageViewCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(SemaphoreCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(SemaphoreCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(ShaderModuleCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(ShaderModuleCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(EventCreateFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(EventCreateFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(MemoryMapFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(MemoryMapFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(SubpassDescriptionFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(SubpassDescriptionFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(DescriptorPoolResetFlagBits)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(DescriptorPoolResetFlags)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(SwapchainCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(SwapchainCreateFlagsKHR)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(DisplayModeCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(DisplayModeCreateFlagsKHR)
+  {
+    return "{}";
+  }
+
+  inline std::string to_string(DisplaySurfaceCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+
+  inline std::string to_string(DisplaySurfaceCreateFlagsKHR)
+  {
+    return "{}";
+  }
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+  inline std::string to_string(AndroidSurfaceCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+  inline std::string to_string(AndroidSurfaceCreateFlagsKHR)
+  {
+    return "{}";
+  }
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+  inline std::string to_string(MirSurfaceCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+  inline std::string to_string(MirSurfaceCreateFlagsKHR)
+  {
+    return "{}";
+  }
+#endif /*VK_USE_PLATFORM_MIR_KHR*/
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+  inline std::string to_string(WaylandSurfaceCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+  inline std::string to_string(WaylandSurfaceCreateFlagsKHR)
+  {
+    return "{}";
+  }
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+  inline std::string to_string(Win32SurfaceCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+  inline std::string to_string(Win32SurfaceCreateFlagsKHR)
+  {
+    return "{}";
+  }
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+  inline std::string to_string(XlibSurfaceCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+  inline std::string to_string(XlibSurfaceCreateFlagsKHR)
+  {
+    return "{}";
+  }
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+  inline std::string to_string(XcbSurfaceCreateFlagBitsKHR)
+  {
+    return "(void)";
+  }
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+  inline std::string to_string(XcbSurfaceCreateFlagsKHR)
+  {
+    return "{}";
+  }
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+  inline std::string to_string(ImageLayout value)
+  {
+    switch (value)
+    {
+    case ImageLayout::eUndefined: return "Undefined";
+    case ImageLayout::eGeneral: return "General";
+    case ImageLayout::eColorAttachmentOptimal: return "ColorAttachmentOptimal";
+    case ImageLayout::eDepthStencilAttachmentOptimal: return "DepthStencilAttachmentOptimal";
+    case ImageLayout::eDepthStencilReadOnlyOptimal: return "DepthStencilReadOnlyOptimal";
+    case ImageLayout::eShaderReadOnlyOptimal: return "ShaderReadOnlyOptimal";
+    case ImageLayout::eTransferSrcOptimal: return "TransferSrcOptimal";
+    case ImageLayout::eTransferDstOptimal: return "TransferDstOptimal";
+    case ImageLayout::ePreinitialized: return "Preinitialized";
+    case ImageLayout::ePresentSrcKHR: return "PresentSrcKHR";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(AttachmentLoadOp value)
+  {
+    switch (value)
+    {
+    case AttachmentLoadOp::eLoad: return "Load";
+    case AttachmentLoadOp::eClear: return "Clear";
+    case AttachmentLoadOp::eDontCare: return "DontCare";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(AttachmentStoreOp value)
+  {
+    switch (value)
+    {
+    case AttachmentStoreOp::eStore: return "Store";
+    case AttachmentStoreOp::eDontCare: return "DontCare";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ImageType value)
+  {
+    switch (value)
+    {
+    case ImageType::e1D: return "1D";
+    case ImageType::e2D: return "2D";
+    case ImageType::e3D: return "3D";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ImageTiling value)
+  {
+    switch (value)
+    {
+    case ImageTiling::eOptimal: return "Optimal";
+    case ImageTiling::eLinear: return "Linear";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ImageViewType value)
+  {
+    switch (value)
+    {
+    case ImageViewType::e1D: return "1D";
+    case ImageViewType::e2D: return "2D";
+    case ImageViewType::e3D: return "3D";
+    case ImageViewType::eCube: return "Cube";
+    case ImageViewType::e1DArray: return "1DArray";
+    case ImageViewType::e2DArray: return "2DArray";
+    case ImageViewType::eCubeArray: return "CubeArray";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CommandBufferLevel value)
+  {
+    switch (value)
+    {
+    case CommandBufferLevel::ePrimary: return "Primary";
+    case CommandBufferLevel::eSecondary: return "Secondary";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ComponentSwizzle value)
+  {
+    switch (value)
+    {
+    case ComponentSwizzle::eIdentity: return "Identity";
+    case ComponentSwizzle::eZero: return "Zero";
+    case ComponentSwizzle::eOne: return "One";
+    case ComponentSwizzle::eR: return "R";
+    case ComponentSwizzle::eG: return "G";
+    case ComponentSwizzle::eB: return "B";
+    case ComponentSwizzle::eA: return "A";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(DescriptorType value)
+  {
+    switch (value)
+    {
+    case DescriptorType::eSampler: return "Sampler";
+    case DescriptorType::eCombinedImageSampler: return "CombinedImageSampler";
+    case DescriptorType::eSampledImage: return "SampledImage";
+    case DescriptorType::eStorageImage: return "StorageImage";
+    case DescriptorType::eUniformTexelBuffer: return "UniformTexelBuffer";
+    case DescriptorType::eStorageTexelBuffer: return "StorageTexelBuffer";
+    case DescriptorType::eUniformBuffer: return "UniformBuffer";
+    case DescriptorType::eStorageBuffer: return "StorageBuffer";
+    case DescriptorType::eUniformBufferDynamic: return "UniformBufferDynamic";
+    case DescriptorType::eStorageBufferDynamic: return "StorageBufferDynamic";
+    case DescriptorType::eInputAttachment: return "InputAttachment";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(QueryType value)
+  {
+    switch (value)
+    {
+    case QueryType::eOcclusion: return "Occlusion";
+    case QueryType::ePipelineStatistics: return "PipelineStatistics";
+    case QueryType::eTimestamp: return "Timestamp";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(BorderColor value)
+  {
+    switch (value)
+    {
+    case BorderColor::eFloatTransparentBlack: return "FloatTransparentBlack";
+    case BorderColor::eIntTransparentBlack: return "IntTransparentBlack";
+    case BorderColor::eFloatOpaqueBlack: return "FloatOpaqueBlack";
+    case BorderColor::eIntOpaqueBlack: return "IntOpaqueBlack";
+    case BorderColor::eFloatOpaqueWhite: return "FloatOpaqueWhite";
+    case BorderColor::eIntOpaqueWhite: return "IntOpaqueWhite";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(PipelineBindPoint value)
+  {
+    switch (value)
+    {
+    case PipelineBindPoint::eGraphics: return "Graphics";
+    case PipelineBindPoint::eCompute: return "Compute";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(PipelineCacheHeaderVersion value)
+  {
+    switch (value)
+    {
+    case PipelineCacheHeaderVersion::eOne: return "One";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(PrimitiveTopology value)
+  {
+    switch (value)
+    {
+    case PrimitiveTopology::ePointList: return "PointList";
+    case PrimitiveTopology::eLineList: return "LineList";
+    case PrimitiveTopology::eLineStrip: return "LineStrip";
+    case PrimitiveTopology::eTriangleList: return "TriangleList";
+    case PrimitiveTopology::eTriangleStrip: return "TriangleStrip";
+    case PrimitiveTopology::eTriangleFan: return "TriangleFan";
+    case PrimitiveTopology::eLineListWithAdjacency: return "LineListWithAdjacency";
+    case PrimitiveTopology::eLineStripWithAdjacency: return "LineStripWithAdjacency";
+    case PrimitiveTopology::eTriangleListWithAdjacency: return "TriangleListWithAdjacency";
+    case PrimitiveTopology::eTriangleStripWithAdjacency: return "TriangleStripWithAdjacency";
+    case PrimitiveTopology::ePatchList: return "PatchList";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SharingMode value)
+  {
+    switch (value)
+    {
+    case SharingMode::eExclusive: return "Exclusive";
+    case SharingMode::eConcurrent: return "Concurrent";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(IndexType value)
+  {
+    switch (value)
+    {
+    case IndexType::eUint16: return "Uint16";
+    case IndexType::eUint32: return "Uint32";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(Filter value)
+  {
+    switch (value)
+    {
+    case Filter::eNearest: return "Nearest";
+    case Filter::eLinear: return "Linear";
+    case Filter::eCubicIMG: return "CubicIMG";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SamplerMipmapMode value)
+  {
+    switch (value)
+    {
+    case SamplerMipmapMode::eNearest: return "Nearest";
+    case SamplerMipmapMode::eLinear: return "Linear";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SamplerAddressMode value)
+  {
+    switch (value)
+    {
+    case SamplerAddressMode::eRepeat: return "Repeat";
+    case SamplerAddressMode::eMirroredRepeat: return "MirroredRepeat";
+    case SamplerAddressMode::eClampToEdge: return "ClampToEdge";
+    case SamplerAddressMode::eClampToBorder: return "ClampToBorder";
+    case SamplerAddressMode::eMirrorClampToEdge: return "MirrorClampToEdge";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CompareOp value)
+  {
+    switch (value)
+    {
+    case CompareOp::eNever: return "Never";
+    case CompareOp::eLess: return "Less";
+    case CompareOp::eEqual: return "Equal";
+    case CompareOp::eLessOrEqual: return "LessOrEqual";
+    case CompareOp::eGreater: return "Greater";
+    case CompareOp::eNotEqual: return "NotEqual";
+    case CompareOp::eGreaterOrEqual: return "GreaterOrEqual";
+    case CompareOp::eAlways: return "Always";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(PolygonMode value)
+  {
+    switch (value)
+    {
+    case PolygonMode::eFill: return "Fill";
+    case PolygonMode::eLine: return "Line";
+    case PolygonMode::ePoint: return "Point";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CullModeFlagBits value)
+  {
+    switch (value)
+    {
+    case CullModeFlagBits::eNone: return "None";
+    case CullModeFlagBits::eFront: return "Front";
+    case CullModeFlagBits::eBack: return "Back";
+    case CullModeFlagBits::eFrontAndBack: return "FrontAndBack";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CullModeFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & CullModeFlagBits::eNone) result += "None | ";
+    if (value & CullModeFlagBits::eFront) result += "Front | ";
+    if (value & CullModeFlagBits::eBack) result += "Back | ";
+    if (value & CullModeFlagBits::eFrontAndBack) result += "FrontAndBack | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(FrontFace value)
+  {
+    switch (value)
+    {
+    case FrontFace::eCounterClockwise: return "CounterClockwise";
+    case FrontFace::eClockwise: return "Clockwise";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(BlendFactor value)
+  {
+    switch (value)
+    {
+    case BlendFactor::eZero: return "Zero";
+    case BlendFactor::eOne: return "One";
+    case BlendFactor::eSrcColor: return "SrcColor";
+    case BlendFactor::eOneMinusSrcColor: return "OneMinusSrcColor";
+    case BlendFactor::eDstColor: return "DstColor";
+    case BlendFactor::eOneMinusDstColor: return "OneMinusDstColor";
+    case BlendFactor::eSrcAlpha: return "SrcAlpha";
+    case BlendFactor::eOneMinusSrcAlpha: return "OneMinusSrcAlpha";
+    case BlendFactor::eDstAlpha: return "DstAlpha";
+    case BlendFactor::eOneMinusDstAlpha: return "OneMinusDstAlpha";
+    case BlendFactor::eConstantColor: return "ConstantColor";
+    case BlendFactor::eOneMinusConstantColor: return "OneMinusConstantColor";
+    case BlendFactor::eConstantAlpha: return "ConstantAlpha";
+    case BlendFactor::eOneMinusConstantAlpha: return "OneMinusConstantAlpha";
+    case BlendFactor::eSrcAlphaSaturate: return "SrcAlphaSaturate";
+    case BlendFactor::eSrc1Color: return "Src1Color";
+    case BlendFactor::eOneMinusSrc1Color: return "OneMinusSrc1Color";
+    case BlendFactor::eSrc1Alpha: return "Src1Alpha";
+    case BlendFactor::eOneMinusSrc1Alpha: return "OneMinusSrc1Alpha";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(BlendOp value)
+  {
+    switch (value)
+    {
+    case BlendOp::eAdd: return "Add";
+    case BlendOp::eSubtract: return "Subtract";
+    case BlendOp::eReverseSubtract: return "ReverseSubtract";
+    case BlendOp::eMin: return "Min";
+    case BlendOp::eMax: return "Max";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(StencilOp value)
+  {
+    switch (value)
+    {
+    case StencilOp::eKeep: return "Keep";
+    case StencilOp::eZero: return "Zero";
+    case StencilOp::eReplace: return "Replace";
+    case StencilOp::eIncrementAndClamp: return "IncrementAndClamp";
+    case StencilOp::eDecrementAndClamp: return "DecrementAndClamp";
+    case StencilOp::eInvert: return "Invert";
+    case StencilOp::eIncrementAndWrap: return "IncrementAndWrap";
+    case StencilOp::eDecrementAndWrap: return "DecrementAndWrap";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(LogicOp value)
+  {
+    switch (value)
+    {
+    case LogicOp::eClear: return "Clear";
+    case LogicOp::eAnd: return "And";
+    case LogicOp::eAndReverse: return "AndReverse";
+    case LogicOp::eCopy: return "Copy";
+    case LogicOp::eAndInverted: return "AndInverted";
+    case LogicOp::eNoOp: return "NoOp";
+    case LogicOp::eXor: return "Xor";
+    case LogicOp::eOr: return "Or";
+    case LogicOp::eNor: return "Nor";
+    case LogicOp::eEquivalent: return "Equivalent";
+    case LogicOp::eInvert: return "Invert";
+    case LogicOp::eOrReverse: return "OrReverse";
+    case LogicOp::eCopyInverted: return "CopyInverted";
+    case LogicOp::eOrInverted: return "OrInverted";
+    case LogicOp::eNand: return "Nand";
+    case LogicOp::eSet: return "Set";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(InternalAllocationType value)
+  {
+    switch (value)
+    {
+    case InternalAllocationType::eExecutable: return "Executable";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SystemAllocationScope value)
+  {
+    switch (value)
+    {
+    case SystemAllocationScope::eCommand: return "Command";
+    case SystemAllocationScope::eObject: return "Object";
+    case SystemAllocationScope::eCache: return "Cache";
+    case SystemAllocationScope::eDevice: return "Device";
+    case SystemAllocationScope::eInstance: return "Instance";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(PhysicalDeviceType value)
+  {
+    switch (value)
+    {
+    case PhysicalDeviceType::eOther: return "Other";
+    case PhysicalDeviceType::eIntegratedGpu: return "IntegratedGpu";
+    case PhysicalDeviceType::eDiscreteGpu: return "DiscreteGpu";
+    case PhysicalDeviceType::eVirtualGpu: return "VirtualGpu";
+    case PhysicalDeviceType::eCpu: return "Cpu";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(VertexInputRate value)
+  {
+    switch (value)
+    {
+    case VertexInputRate::eVertex: return "Vertex";
+    case VertexInputRate::eInstance: return "Instance";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(Format value)
+  {
+    switch (value)
+    {
+    case Format::eUndefined: return "Undefined";
+    case Format::eR4G4UnormPack8: return "R4G4UnormPack8";
+    case Format::eR4G4B4A4UnormPack16: return "R4G4B4A4UnormPack16";
+    case Format::eB4G4R4A4UnormPack16: return "B4G4R4A4UnormPack16";
+    case Format::eR5G6B5UnormPack16: return "R5G6B5UnormPack16";
+    case Format::eB5G6R5UnormPack16: return "B5G6R5UnormPack16";
+    case Format::eR5G5B5A1UnormPack16: return "R5G5B5A1UnormPack16";
+    case Format::eB5G5R5A1UnormPack16: return "B5G5R5A1UnormPack16";
+    case Format::eA1R5G5B5UnormPack16: return "A1R5G5B5UnormPack16";
+    case Format::eR8Unorm: return "R8Unorm";
+    case Format::eR8Snorm: return "R8Snorm";
+    case Format::eR8Uscaled: return "R8Uscaled";
+    case Format::eR8Sscaled: return "R8Sscaled";
+    case Format::eR8Uint: return "R8Uint";
+    case Format::eR8Sint: return "R8Sint";
+    case Format::eR8Srgb: return "R8Srgb";
+    case Format::eR8G8Unorm: return "R8G8Unorm";
+    case Format::eR8G8Snorm: return "R8G8Snorm";
+    case Format::eR8G8Uscaled: return "R8G8Uscaled";
+    case Format::eR8G8Sscaled: return "R8G8Sscaled";
+    case Format::eR8G8Uint: return "R8G8Uint";
+    case Format::eR8G8Sint: return "R8G8Sint";
+    case Format::eR8G8Srgb: return "R8G8Srgb";
+    case Format::eR8G8B8Unorm: return "R8G8B8Unorm";
+    case Format::eR8G8B8Snorm: return "R8G8B8Snorm";
+    case Format::eR8G8B8Uscaled: return "R8G8B8Uscaled";
+    case Format::eR8G8B8Sscaled: return "R8G8B8Sscaled";
+    case Format::eR8G8B8Uint: return "R8G8B8Uint";
+    case Format::eR8G8B8Sint: return "R8G8B8Sint";
+    case Format::eR8G8B8Srgb: return "R8G8B8Srgb";
+    case Format::eB8G8R8Unorm: return "B8G8R8Unorm";
+    case Format::eB8G8R8Snorm: return "B8G8R8Snorm";
+    case Format::eB8G8R8Uscaled: return "B8G8R8Uscaled";
+    case Format::eB8G8R8Sscaled: return "B8G8R8Sscaled";
+    case Format::eB8G8R8Uint: return "B8G8R8Uint";
+    case Format::eB8G8R8Sint: return "B8G8R8Sint";
+    case Format::eB8G8R8Srgb: return "B8G8R8Srgb";
+    case Format::eR8G8B8A8Unorm: return "R8G8B8A8Unorm";
+    case Format::eR8G8B8A8Snorm: return "R8G8B8A8Snorm";
+    case Format::eR8G8B8A8Uscaled: return "R8G8B8A8Uscaled";
+    case Format::eR8G8B8A8Sscaled: return "R8G8B8A8Sscaled";
+    case Format::eR8G8B8A8Uint: return "R8G8B8A8Uint";
+    case Format::eR8G8B8A8Sint: return "R8G8B8A8Sint";
+    case Format::eR8G8B8A8Srgb: return "R8G8B8A8Srgb";
+    case Format::eB8G8R8A8Unorm: return "B8G8R8A8Unorm";
+    case Format::eB8G8R8A8Snorm: return "B8G8R8A8Snorm";
+    case Format::eB8G8R8A8Uscaled: return "B8G8R8A8Uscaled";
+    case Format::eB8G8R8A8Sscaled: return "B8G8R8A8Sscaled";
+    case Format::eB8G8R8A8Uint: return "B8G8R8A8Uint";
+    case Format::eB8G8R8A8Sint: return "B8G8R8A8Sint";
+    case Format::eB8G8R8A8Srgb: return "B8G8R8A8Srgb";
+    case Format::eA8B8G8R8UnormPack32: return "A8B8G8R8UnormPack32";
+    case Format::eA8B8G8R8SnormPack32: return "A8B8G8R8SnormPack32";
+    case Format::eA8B8G8R8UscaledPack32: return "A8B8G8R8UscaledPack32";
+    case Format::eA8B8G8R8SscaledPack32: return "A8B8G8R8SscaledPack32";
+    case Format::eA8B8G8R8UintPack32: return "A8B8G8R8UintPack32";
+    case Format::eA8B8G8R8SintPack32: return "A8B8G8R8SintPack32";
+    case Format::eA8B8G8R8SrgbPack32: return "A8B8G8R8SrgbPack32";
+    case Format::eA2R10G10B10UnormPack32: return "A2R10G10B10UnormPack32";
+    case Format::eA2R10G10B10SnormPack32: return "A2R10G10B10SnormPack32";
+    case Format::eA2R10G10B10UscaledPack32: return "A2R10G10B10UscaledPack32";
+    case Format::eA2R10G10B10SscaledPack32: return "A2R10G10B10SscaledPack32";
+    case Format::eA2R10G10B10UintPack32: return "A2R10G10B10UintPack32";
+    case Format::eA2R10G10B10SintPack32: return "A2R10G10B10SintPack32";
+    case Format::eA2B10G10R10UnormPack32: return "A2B10G10R10UnormPack32";
+    case Format::eA2B10G10R10SnormPack32: return "A2B10G10R10SnormPack32";
+    case Format::eA2B10G10R10UscaledPack32: return "A2B10G10R10UscaledPack32";
+    case Format::eA2B10G10R10SscaledPack32: return "A2B10G10R10SscaledPack32";
+    case Format::eA2B10G10R10UintPack32: return "A2B10G10R10UintPack32";
+    case Format::eA2B10G10R10SintPack32: return "A2B10G10R10SintPack32";
+    case Format::eR16Unorm: return "R16Unorm";
+    case Format::eR16Snorm: return "R16Snorm";
+    case Format::eR16Uscaled: return "R16Uscaled";
+    case Format::eR16Sscaled: return "R16Sscaled";
+    case Format::eR16Uint: return "R16Uint";
+    case Format::eR16Sint: return "R16Sint";
+    case Format::eR16Sfloat: return "R16Sfloat";
+    case Format::eR16G16Unorm: return "R16G16Unorm";
+    case Format::eR16G16Snorm: return "R16G16Snorm";
+    case Format::eR16G16Uscaled: return "R16G16Uscaled";
+    case Format::eR16G16Sscaled: return "R16G16Sscaled";
+    case Format::eR16G16Uint: return "R16G16Uint";
+    case Format::eR16G16Sint: return "R16G16Sint";
+    case Format::eR16G16Sfloat: return "R16G16Sfloat";
+    case Format::eR16G16B16Unorm: return "R16G16B16Unorm";
+    case Format::eR16G16B16Snorm: return "R16G16B16Snorm";
+    case Format::eR16G16B16Uscaled: return "R16G16B16Uscaled";
+    case Format::eR16G16B16Sscaled: return "R16G16B16Sscaled";
+    case Format::eR16G16B16Uint: return "R16G16B16Uint";
+    case Format::eR16G16B16Sint: return "R16G16B16Sint";
+    case Format::eR16G16B16Sfloat: return "R16G16B16Sfloat";
+    case Format::eR16G16B16A16Unorm: return "R16G16B16A16Unorm";
+    case Format::eR16G16B16A16Snorm: return "R16G16B16A16Snorm";
+    case Format::eR16G16B16A16Uscaled: return "R16G16B16A16Uscaled";
+    case Format::eR16G16B16A16Sscaled: return "R16G16B16A16Sscaled";
+    case Format::eR16G16B16A16Uint: return "R16G16B16A16Uint";
+    case Format::eR16G16B16A16Sint: return "R16G16B16A16Sint";
+    case Format::eR16G16B16A16Sfloat: return "R16G16B16A16Sfloat";
+    case Format::eR32Uint: return "R32Uint";
+    case Format::eR32Sint: return "R32Sint";
+    case Format::eR32Sfloat: return "R32Sfloat";
+    case Format::eR32G32Uint: return "R32G32Uint";
+    case Format::eR32G32Sint: return "R32G32Sint";
+    case Format::eR32G32Sfloat: return "R32G32Sfloat";
+    case Format::eR32G32B32Uint: return "R32G32B32Uint";
+    case Format::eR32G32B32Sint: return "R32G32B32Sint";
+    case Format::eR32G32B32Sfloat: return "R32G32B32Sfloat";
+    case Format::eR32G32B32A32Uint: return "R32G32B32A32Uint";
+    case Format::eR32G32B32A32Sint: return "R32G32B32A32Sint";
+    case Format::eR32G32B32A32Sfloat: return "R32G32B32A32Sfloat";
+    case Format::eR64Uint: return "R64Uint";
+    case Format::eR64Sint: return "R64Sint";
+    case Format::eR64Sfloat: return "R64Sfloat";
+    case Format::eR64G64Uint: return "R64G64Uint";
+    case Format::eR64G64Sint: return "R64G64Sint";
+    case Format::eR64G64Sfloat: return "R64G64Sfloat";
+    case Format::eR64G64B64Uint: return "R64G64B64Uint";
+    case Format::eR64G64B64Sint: return "R64G64B64Sint";
+    case Format::eR64G64B64Sfloat: return "R64G64B64Sfloat";
+    case Format::eR64G64B64A64Uint: return "R64G64B64A64Uint";
+    case Format::eR64G64B64A64Sint: return "R64G64B64A64Sint";
+    case Format::eR64G64B64A64Sfloat: return "R64G64B64A64Sfloat";
+    case Format::eB10G11R11UfloatPack32: return "B10G11R11UfloatPack32";
+    case Format::eE5B9G9R9UfloatPack32: return "E5B9G9R9UfloatPack32";
+    case Format::eD16Unorm: return "D16Unorm";
+    case Format::eX8D24UnormPack32: return "X8D24UnormPack32";
+    case Format::eD32Sfloat: return "D32Sfloat";
+    case Format::eS8Uint: return "S8Uint";
+    case Format::eD16UnormS8Uint: return "D16UnormS8Uint";
+    case Format::eD24UnormS8Uint: return "D24UnormS8Uint";
+    case Format::eD32SfloatS8Uint: return "D32SfloatS8Uint";
+    case Format::eBc1RgbUnormBlock: return "Bc1RgbUnormBlock";
+    case Format::eBc1RgbSrgbBlock: return "Bc1RgbSrgbBlock";
+    case Format::eBc1RgbaUnormBlock: return "Bc1RgbaUnormBlock";
+    case Format::eBc1RgbaSrgbBlock: return "Bc1RgbaSrgbBlock";
+    case Format::eBc2UnormBlock: return "Bc2UnormBlock";
+    case Format::eBc2SrgbBlock: return "Bc2SrgbBlock";
+    case Format::eBc3UnormBlock: return "Bc3UnormBlock";
+    case Format::eBc3SrgbBlock: return "Bc3SrgbBlock";
+    case Format::eBc4UnormBlock: return "Bc4UnormBlock";
+    case Format::eBc4SnormBlock: return "Bc4SnormBlock";
+    case Format::eBc5UnormBlock: return "Bc5UnormBlock";
+    case Format::eBc5SnormBlock: return "Bc5SnormBlock";
+    case Format::eBc6HUfloatBlock: return "Bc6HUfloatBlock";
+    case Format::eBc6HSfloatBlock: return "Bc6HSfloatBlock";
+    case Format::eBc7UnormBlock: return "Bc7UnormBlock";
+    case Format::eBc7SrgbBlock: return "Bc7SrgbBlock";
+    case Format::eEtc2R8G8B8UnormBlock: return "Etc2R8G8B8UnormBlock";
+    case Format::eEtc2R8G8B8SrgbBlock: return "Etc2R8G8B8SrgbBlock";
+    case Format::eEtc2R8G8B8A1UnormBlock: return "Etc2R8G8B8A1UnormBlock";
+    case Format::eEtc2R8G8B8A1SrgbBlock: return "Etc2R8G8B8A1SrgbBlock";
+    case Format::eEtc2R8G8B8A8UnormBlock: return "Etc2R8G8B8A8UnormBlock";
+    case Format::eEtc2R8G8B8A8SrgbBlock: return "Etc2R8G8B8A8SrgbBlock";
+    case Format::eEacR11UnormBlock: return "EacR11UnormBlock";
+    case Format::eEacR11SnormBlock: return "EacR11SnormBlock";
+    case Format::eEacR11G11UnormBlock: return "EacR11G11UnormBlock";
+    case Format::eEacR11G11SnormBlock: return "EacR11G11SnormBlock";
+    case Format::eAstc4x4UnormBlock: return "Astc4x4UnormBlock";
+    case Format::eAstc4x4SrgbBlock: return "Astc4x4SrgbBlock";
+    case Format::eAstc5x4UnormBlock: return "Astc5x4UnormBlock";
+    case Format::eAstc5x4SrgbBlock: return "Astc5x4SrgbBlock";
+    case Format::eAstc5x5UnormBlock: return "Astc5x5UnormBlock";
+    case Format::eAstc5x5SrgbBlock: return "Astc5x5SrgbBlock";
+    case Format::eAstc6x5UnormBlock: return "Astc6x5UnormBlock";
+    case Format::eAstc6x5SrgbBlock: return "Astc6x5SrgbBlock";
+    case Format::eAstc6x6UnormBlock: return "Astc6x6UnormBlock";
+    case Format::eAstc6x6SrgbBlock: return "Astc6x6SrgbBlock";
+    case Format::eAstc8x5UnormBlock: return "Astc8x5UnormBlock";
+    case Format::eAstc8x5SrgbBlock: return "Astc8x5SrgbBlock";
+    case Format::eAstc8x6UnormBlock: return "Astc8x6UnormBlock";
+    case Format::eAstc8x6SrgbBlock: return "Astc8x6SrgbBlock";
+    case Format::eAstc8x8UnormBlock: return "Astc8x8UnormBlock";
+    case Format::eAstc8x8SrgbBlock: return "Astc8x8SrgbBlock";
+    case Format::eAstc10x5UnormBlock: return "Astc10x5UnormBlock";
+    case Format::eAstc10x5SrgbBlock: return "Astc10x5SrgbBlock";
+    case Format::eAstc10x6UnormBlock: return "Astc10x6UnormBlock";
+    case Format::eAstc10x6SrgbBlock: return "Astc10x6SrgbBlock";
+    case Format::eAstc10x8UnormBlock: return "Astc10x8UnormBlock";
+    case Format::eAstc10x8SrgbBlock: return "Astc10x8SrgbBlock";
+    case Format::eAstc10x10UnormBlock: return "Astc10x10UnormBlock";
+    case Format::eAstc10x10SrgbBlock: return "Astc10x10SrgbBlock";
+    case Format::eAstc12x10UnormBlock: return "Astc12x10UnormBlock";
+    case Format::eAstc12x10SrgbBlock: return "Astc12x10SrgbBlock";
+    case Format::eAstc12x12UnormBlock: return "Astc12x12UnormBlock";
+    case Format::eAstc12x12SrgbBlock: return "Astc12x12SrgbBlock";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(StructureType value)
+  {
+    switch (value)
+    {
+    case StructureType::eApplicationInfo: return "ApplicationInfo";
+    case StructureType::eInstanceCreateInfo: return "InstanceCreateInfo";
+    case StructureType::eDeviceQueueCreateInfo: return "DeviceQueueCreateInfo";
+    case StructureType::eDeviceCreateInfo: return "DeviceCreateInfo";
+    case StructureType::eSubmitInfo: return "SubmitInfo";
+    case StructureType::eMemoryAllocateInfo: return "MemoryAllocateInfo";
+    case StructureType::eMappedMemoryRange: return "MappedMemoryRange";
+    case StructureType::eBindSparseInfo: return "BindSparseInfo";
+    case StructureType::eFenceCreateInfo: return "FenceCreateInfo";
+    case StructureType::eSemaphoreCreateInfo: return "SemaphoreCreateInfo";
+    case StructureType::eEventCreateInfo: return "EventCreateInfo";
+    case StructureType::eQueryPoolCreateInfo: return "QueryPoolCreateInfo";
+    case StructureType::eBufferCreateInfo: return "BufferCreateInfo";
+    case StructureType::eBufferViewCreateInfo: return "BufferViewCreateInfo";
+    case StructureType::eImageCreateInfo: return "ImageCreateInfo";
+    case StructureType::eImageViewCreateInfo: return "ImageViewCreateInfo";
+    case StructureType::eShaderModuleCreateInfo: return "ShaderModuleCreateInfo";
+    case StructureType::ePipelineCacheCreateInfo: return "PipelineCacheCreateInfo";
+    case StructureType::ePipelineShaderStageCreateInfo: return "PipelineShaderStageCreateInfo";
+    case StructureType::ePipelineVertexInputStateCreateInfo: return "PipelineVertexInputStateCreateInfo";
+    case StructureType::ePipelineInputAssemblyStateCreateInfo: return "PipelineInputAssemblyStateCreateInfo";
+    case StructureType::ePipelineTessellationStateCreateInfo: return "PipelineTessellationStateCreateInfo";
+    case StructureType::ePipelineViewportStateCreateInfo: return "PipelineViewportStateCreateInfo";
+    case StructureType::ePipelineRasterizationStateCreateInfo: return "PipelineRasterizationStateCreateInfo";
+    case StructureType::ePipelineMultisampleStateCreateInfo: return "PipelineMultisampleStateCreateInfo";
+    case StructureType::ePipelineDepthStencilStateCreateInfo: return "PipelineDepthStencilStateCreateInfo";
+    case StructureType::ePipelineColorBlendStateCreateInfo: return "PipelineColorBlendStateCreateInfo";
+    case StructureType::ePipelineDynamicStateCreateInfo: return "PipelineDynamicStateCreateInfo";
+    case StructureType::eGraphicsPipelineCreateInfo: return "GraphicsPipelineCreateInfo";
+    case StructureType::eComputePipelineCreateInfo: return "ComputePipelineCreateInfo";
+    case StructureType::ePipelineLayoutCreateInfo: return "PipelineLayoutCreateInfo";
+    case StructureType::eSamplerCreateInfo: return "SamplerCreateInfo";
+    case StructureType::eDescriptorSetLayoutCreateInfo: return "DescriptorSetLayoutCreateInfo";
+    case StructureType::eDescriptorPoolCreateInfo: return "DescriptorPoolCreateInfo";
+    case StructureType::eDescriptorSetAllocateInfo: return "DescriptorSetAllocateInfo";
+    case StructureType::eWriteDescriptorSet: return "WriteDescriptorSet";
+    case StructureType::eCopyDescriptorSet: return "CopyDescriptorSet";
+    case StructureType::eFramebufferCreateInfo: return "FramebufferCreateInfo";
+    case StructureType::eRenderPassCreateInfo: return "RenderPassCreateInfo";
+    case StructureType::eCommandPoolCreateInfo: return "CommandPoolCreateInfo";
+    case StructureType::eCommandBufferAllocateInfo: return "CommandBufferAllocateInfo";
+    case StructureType::eCommandBufferInheritanceInfo: return "CommandBufferInheritanceInfo";
+    case StructureType::eCommandBufferBeginInfo: return "CommandBufferBeginInfo";
+    case StructureType::eRenderPassBeginInfo: return "RenderPassBeginInfo";
+    case StructureType::eBufferMemoryBarrier: return "BufferMemoryBarrier";
+    case StructureType::eImageMemoryBarrier: return "ImageMemoryBarrier";
+    case StructureType::eMemoryBarrier: return "MemoryBarrier";
+    case StructureType::eLoaderInstanceCreateInfo: return "LoaderInstanceCreateInfo";
+    case StructureType::eLoaderDeviceCreateInfo: return "LoaderDeviceCreateInfo";
+    case StructureType::eSwapchainCreateInfoKHR: return "SwapchainCreateInfoKHR";
+    case StructureType::ePresentInfoKHR: return "PresentInfoKHR";
+    case StructureType::eDisplayModeCreateInfoKHR: return "DisplayModeCreateInfoKHR";
+    case StructureType::eDisplaySurfaceCreateInfoKHR: return "DisplaySurfaceCreateInfoKHR";
+    case StructureType::eDisplayPresentInfoKHR: return "DisplayPresentInfoKHR";
+    case StructureType::eXlibSurfaceCreateInfoKHR: return "XlibSurfaceCreateInfoKHR";
+    case StructureType::eXcbSurfaceCreateInfoKHR: return "XcbSurfaceCreateInfoKHR";
+    case StructureType::eWaylandSurfaceCreateInfoKHR: return "WaylandSurfaceCreateInfoKHR";
+    case StructureType::eMirSurfaceCreateInfoKHR: return "MirSurfaceCreateInfoKHR";
+    case StructureType::eAndroidSurfaceCreateInfoKHR: return "AndroidSurfaceCreateInfoKHR";
+    case StructureType::eWin32SurfaceCreateInfoKHR: return "Win32SurfaceCreateInfoKHR";
+    case StructureType::eDebugReportCallbackCreateInfoEXT: return "DebugReportCallbackCreateInfoEXT";
+    case StructureType::ePipelineRasterizationStateRasterizationOrderAMD: return "PipelineRasterizationStateRasterizationOrderAMD";
+    case StructureType::eDebugMarkerObjectNameInfoEXT: return "DebugMarkerObjectNameInfoEXT";
+    case StructureType::eDebugMarkerObjectTagInfoEXT: return "DebugMarkerObjectTagInfoEXT";
+    case StructureType::eDebugMarkerMarkerInfoEXT: return "DebugMarkerMarkerInfoEXT";
+    case StructureType::eDedicatedAllocationImageCreateInfoNV: return "DedicatedAllocationImageCreateInfoNV";
+    case StructureType::eDedicatedAllocationBufferCreateInfoNV: return "DedicatedAllocationBufferCreateInfoNV";
+    case StructureType::eDedicatedAllocationMemoryAllocateInfoNV: return "DedicatedAllocationMemoryAllocateInfoNV";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SubpassContents value)
+  {
+    switch (value)
+    {
+    case SubpassContents::eInline: return "Inline";
+    case SubpassContents::eSecondaryCommandBuffers: return "SecondaryCommandBuffers";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(DynamicState value)
+  {
+    switch (value)
+    {
+    case DynamicState::eViewport: return "Viewport";
+    case DynamicState::eScissor: return "Scissor";
+    case DynamicState::eLineWidth: return "LineWidth";
+    case DynamicState::eDepthBias: return "DepthBias";
+    case DynamicState::eBlendConstants: return "BlendConstants";
+    case DynamicState::eDepthBounds: return "DepthBounds";
+    case DynamicState::eStencilCompareMask: return "StencilCompareMask";
+    case DynamicState::eStencilWriteMask: return "StencilWriteMask";
+    case DynamicState::eStencilReference: return "StencilReference";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(QueueFlagBits value)
+  {
+    switch (value)
+    {
+    case QueueFlagBits::eGraphics: return "Graphics";
+    case QueueFlagBits::eCompute: return "Compute";
+    case QueueFlagBits::eTransfer: return "Transfer";
+    case QueueFlagBits::eSparseBinding: return "SparseBinding";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(QueueFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & QueueFlagBits::eGraphics) result += "Graphics | ";
+    if (value & QueueFlagBits::eCompute) result += "Compute | ";
+    if (value & QueueFlagBits::eTransfer) result += "Transfer | ";
+    if (value & QueueFlagBits::eSparseBinding) result += "SparseBinding | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(MemoryPropertyFlagBits value)
+  {
+    switch (value)
+    {
+    case MemoryPropertyFlagBits::eDeviceLocal: return "DeviceLocal";
+    case MemoryPropertyFlagBits::eHostVisible: return "HostVisible";
+    case MemoryPropertyFlagBits::eHostCoherent: return "HostCoherent";
+    case MemoryPropertyFlagBits::eHostCached: return "HostCached";
+    case MemoryPropertyFlagBits::eLazilyAllocated: return "LazilyAllocated";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(MemoryPropertyFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & MemoryPropertyFlagBits::eDeviceLocal) result += "DeviceLocal | ";
+    if (value & MemoryPropertyFlagBits::eHostVisible) result += "HostVisible | ";
+    if (value & MemoryPropertyFlagBits::eHostCoherent) result += "HostCoherent | ";
+    if (value & MemoryPropertyFlagBits::eHostCached) result += "HostCached | ";
+    if (value & MemoryPropertyFlagBits::eLazilyAllocated) result += "LazilyAllocated | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(MemoryHeapFlagBits value)
+  {
+    switch (value)
+    {
+    case MemoryHeapFlagBits::eDeviceLocal: return "DeviceLocal";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(MemoryHeapFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & MemoryHeapFlagBits::eDeviceLocal) result += "DeviceLocal | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(AccessFlagBits value)
+  {
+    switch (value)
+    {
+    case AccessFlagBits::eIndirectCommandRead: return "IndirectCommandRead";
+    case AccessFlagBits::eIndexRead: return "IndexRead";
+    case AccessFlagBits::eVertexAttributeRead: return "VertexAttributeRead";
+    case AccessFlagBits::eUniformRead: return "UniformRead";
+    case AccessFlagBits::eInputAttachmentRead: return "InputAttachmentRead";
+    case AccessFlagBits::eShaderRead: return "ShaderRead";
+    case AccessFlagBits::eShaderWrite: return "ShaderWrite";
+    case AccessFlagBits::eColorAttachmentRead: return "ColorAttachmentRead";
+    case AccessFlagBits::eColorAttachmentWrite: return "ColorAttachmentWrite";
+    case AccessFlagBits::eDepthStencilAttachmentRead: return "DepthStencilAttachmentRead";
+    case AccessFlagBits::eDepthStencilAttachmentWrite: return "DepthStencilAttachmentWrite";
+    case AccessFlagBits::eTransferRead: return "TransferRead";
+    case AccessFlagBits::eTransferWrite: return "TransferWrite";
+    case AccessFlagBits::eHostRead: return "HostRead";
+    case AccessFlagBits::eHostWrite: return "HostWrite";
+    case AccessFlagBits::eMemoryRead: return "MemoryRead";
+    case AccessFlagBits::eMemoryWrite: return "MemoryWrite";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(AccessFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & AccessFlagBits::eIndirectCommandRead) result += "IndirectCommandRead | ";
+    if (value & AccessFlagBits::eIndexRead) result += "IndexRead | ";
+    if (value & AccessFlagBits::eVertexAttributeRead) result += "VertexAttributeRead | ";
+    if (value & AccessFlagBits::eUniformRead) result += "UniformRead | ";
+    if (value & AccessFlagBits::eInputAttachmentRead) result += "InputAttachmentRead | ";
+    if (value & AccessFlagBits::eShaderRead) result += "ShaderRead | ";
+    if (value & AccessFlagBits::eShaderWrite) result += "ShaderWrite | ";
+    if (value & AccessFlagBits::eColorAttachmentRead) result += "ColorAttachmentRead | ";
+    if (value & AccessFlagBits::eColorAttachmentWrite) result += "ColorAttachmentWrite | ";
+    if (value & AccessFlagBits::eDepthStencilAttachmentRead) result += "DepthStencilAttachmentRead | ";
+    if (value & AccessFlagBits::eDepthStencilAttachmentWrite) result += "DepthStencilAttachmentWrite | ";
+    if (value & AccessFlagBits::eTransferRead) result += "TransferRead | ";
+    if (value & AccessFlagBits::eTransferWrite) result += "TransferWrite | ";
+    if (value & AccessFlagBits::eHostRead) result += "HostRead | ";
+    if (value & AccessFlagBits::eHostWrite) result += "HostWrite | ";
+    if (value & AccessFlagBits::eMemoryRead) result += "MemoryRead | ";
+    if (value & AccessFlagBits::eMemoryWrite) result += "MemoryWrite | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(BufferUsageFlagBits value)
+  {
+    switch (value)
+    {
+    case BufferUsageFlagBits::eTransferSrc: return "TransferSrc";
+    case BufferUsageFlagBits::eTransferDst: return "TransferDst";
+    case BufferUsageFlagBits::eUniformTexelBuffer: return "UniformTexelBuffer";
+    case BufferUsageFlagBits::eStorageTexelBuffer: return "StorageTexelBuffer";
+    case BufferUsageFlagBits::eUniformBuffer: return "UniformBuffer";
+    case BufferUsageFlagBits::eStorageBuffer: return "StorageBuffer";
+    case BufferUsageFlagBits::eIndexBuffer: return "IndexBuffer";
+    case BufferUsageFlagBits::eVertexBuffer: return "VertexBuffer";
+    case BufferUsageFlagBits::eIndirectBuffer: return "IndirectBuffer";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(BufferUsageFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & BufferUsageFlagBits::eTransferSrc) result += "TransferSrc | ";
+    if (value & BufferUsageFlagBits::eTransferDst) result += "TransferDst | ";
+    if (value & BufferUsageFlagBits::eUniformTexelBuffer) result += "UniformTexelBuffer | ";
+    if (value & BufferUsageFlagBits::eStorageTexelBuffer) result += "StorageTexelBuffer | ";
+    if (value & BufferUsageFlagBits::eUniformBuffer) result += "UniformBuffer | ";
+    if (value & BufferUsageFlagBits::eStorageBuffer) result += "StorageBuffer | ";
+    if (value & BufferUsageFlagBits::eIndexBuffer) result += "IndexBuffer | ";
+    if (value & BufferUsageFlagBits::eVertexBuffer) result += "VertexBuffer | ";
+    if (value & BufferUsageFlagBits::eIndirectBuffer) result += "IndirectBuffer | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(BufferCreateFlagBits value)
+  {
+    switch (value)
+    {
+    case BufferCreateFlagBits::eSparseBinding: return "SparseBinding";
+    case BufferCreateFlagBits::eSparseResidency: return "SparseResidency";
+    case BufferCreateFlagBits::eSparseAliased: return "SparseAliased";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(BufferCreateFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & BufferCreateFlagBits::eSparseBinding) result += "SparseBinding | ";
+    if (value & BufferCreateFlagBits::eSparseResidency) result += "SparseResidency | ";
+    if (value & BufferCreateFlagBits::eSparseAliased) result += "SparseAliased | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(ShaderStageFlagBits value)
+  {
+    switch (value)
+    {
+    case ShaderStageFlagBits::eVertex: return "Vertex";
+    case ShaderStageFlagBits::eTessellationControl: return "TessellationControl";
+    case ShaderStageFlagBits::eTessellationEvaluation: return "TessellationEvaluation";
+    case ShaderStageFlagBits::eGeometry: return "Geometry";
+    case ShaderStageFlagBits::eFragment: return "Fragment";
+    case ShaderStageFlagBits::eCompute: return "Compute";
+    case ShaderStageFlagBits::eAllGraphics: return "AllGraphics";
+    case ShaderStageFlagBits::eAll: return "All";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ShaderStageFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & ShaderStageFlagBits::eVertex) result += "Vertex | ";
+    if (value & ShaderStageFlagBits::eTessellationControl) result += "TessellationControl | ";
+    if (value & ShaderStageFlagBits::eTessellationEvaluation) result += "TessellationEvaluation | ";
+    if (value & ShaderStageFlagBits::eGeometry) result += "Geometry | ";
+    if (value & ShaderStageFlagBits::eFragment) result += "Fragment | ";
+    if (value & ShaderStageFlagBits::eCompute) result += "Compute | ";
+    if (value & ShaderStageFlagBits::eAllGraphics) result += "AllGraphics | ";
+    if (value & ShaderStageFlagBits::eAll) result += "All | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(ImageUsageFlagBits value)
+  {
+    switch (value)
+    {
+    case ImageUsageFlagBits::eTransferSrc: return "TransferSrc";
+    case ImageUsageFlagBits::eTransferDst: return "TransferDst";
+    case ImageUsageFlagBits::eSampled: return "Sampled";
+    case ImageUsageFlagBits::eStorage: return "Storage";
+    case ImageUsageFlagBits::eColorAttachment: return "ColorAttachment";
+    case ImageUsageFlagBits::eDepthStencilAttachment: return "DepthStencilAttachment";
+    case ImageUsageFlagBits::eTransientAttachment: return "TransientAttachment";
+    case ImageUsageFlagBits::eInputAttachment: return "InputAttachment";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ImageUsageFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & ImageUsageFlagBits::eTransferSrc) result += "TransferSrc | ";
+    if (value & ImageUsageFlagBits::eTransferDst) result += "TransferDst | ";
+    if (value & ImageUsageFlagBits::eSampled) result += "Sampled | ";
+    if (value & ImageUsageFlagBits::eStorage) result += "Storage | ";
+    if (value & ImageUsageFlagBits::eColorAttachment) result += "ColorAttachment | ";
+    if (value & ImageUsageFlagBits::eDepthStencilAttachment) result += "DepthStencilAttachment | ";
+    if (value & ImageUsageFlagBits::eTransientAttachment) result += "TransientAttachment | ";
+    if (value & ImageUsageFlagBits::eInputAttachment) result += "InputAttachment | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(ImageCreateFlagBits value)
+  {
+    switch (value)
+    {
+    case ImageCreateFlagBits::eSparseBinding: return "SparseBinding";
+    case ImageCreateFlagBits::eSparseResidency: return "SparseResidency";
+    case ImageCreateFlagBits::eSparseAliased: return "SparseAliased";
+    case ImageCreateFlagBits::eMutableFormat: return "MutableFormat";
+    case ImageCreateFlagBits::eCubeCompatible: return "CubeCompatible";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ImageCreateFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & ImageCreateFlagBits::eSparseBinding) result += "SparseBinding | ";
+    if (value & ImageCreateFlagBits::eSparseResidency) result += "SparseResidency | ";
+    if (value & ImageCreateFlagBits::eSparseAliased) result += "SparseAliased | ";
+    if (value & ImageCreateFlagBits::eMutableFormat) result += "MutableFormat | ";
+    if (value & ImageCreateFlagBits::eCubeCompatible) result += "CubeCompatible | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(PipelineCreateFlagBits value)
+  {
+    switch (value)
+    {
+    case PipelineCreateFlagBits::eDisableOptimization: return "DisableOptimization";
+    case PipelineCreateFlagBits::eAllowDerivatives: return "AllowDerivatives";
+    case PipelineCreateFlagBits::eDerivative: return "Derivative";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(PipelineCreateFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & PipelineCreateFlagBits::eDisableOptimization) result += "DisableOptimization | ";
+    if (value & PipelineCreateFlagBits::eAllowDerivatives) result += "AllowDerivatives | ";
+    if (value & PipelineCreateFlagBits::eDerivative) result += "Derivative | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(ColorComponentFlagBits value)
+  {
+    switch (value)
+    {
+    case ColorComponentFlagBits::eR: return "R";
+    case ColorComponentFlagBits::eG: return "G";
+    case ColorComponentFlagBits::eB: return "B";
+    case ColorComponentFlagBits::eA: return "A";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ColorComponentFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & ColorComponentFlagBits::eR) result += "R | ";
+    if (value & ColorComponentFlagBits::eG) result += "G | ";
+    if (value & ColorComponentFlagBits::eB) result += "B | ";
+    if (value & ColorComponentFlagBits::eA) result += "A | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(FenceCreateFlagBits value)
+  {
+    switch (value)
+    {
+    case FenceCreateFlagBits::eSignaled: return "Signaled";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(FenceCreateFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & FenceCreateFlagBits::eSignaled) result += "Signaled | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(FormatFeatureFlagBits value)
+  {
+    switch (value)
+    {
+    case FormatFeatureFlagBits::eSampledImage: return "SampledImage";
+    case FormatFeatureFlagBits::eStorageImage: return "StorageImage";
+    case FormatFeatureFlagBits::eStorageImageAtomic: return "StorageImageAtomic";
+    case FormatFeatureFlagBits::eUniformTexelBuffer: return "UniformTexelBuffer";
+    case FormatFeatureFlagBits::eStorageTexelBuffer: return "StorageTexelBuffer";
+    case FormatFeatureFlagBits::eStorageTexelBufferAtomic: return "StorageTexelBufferAtomic";
+    case FormatFeatureFlagBits::eVertexBuffer: return "VertexBuffer";
+    case FormatFeatureFlagBits::eColorAttachment: return "ColorAttachment";
+    case FormatFeatureFlagBits::eColorAttachmentBlend: return "ColorAttachmentBlend";
+    case FormatFeatureFlagBits::eDepthStencilAttachment: return "DepthStencilAttachment";
+    case FormatFeatureFlagBits::eBlitSrc: return "BlitSrc";
+    case FormatFeatureFlagBits::eBlitDst: return "BlitDst";
+    case FormatFeatureFlagBits::eSampledImageFilterLinear: return "SampledImageFilterLinear";
+    case FormatFeatureFlagBits::eSampledImageFilterCubicIMG: return "SampledImageFilterCubicIMG";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(FormatFeatureFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & FormatFeatureFlagBits::eSampledImage) result += "SampledImage | ";
+    if (value & FormatFeatureFlagBits::eStorageImage) result += "StorageImage | ";
+    if (value & FormatFeatureFlagBits::eStorageImageAtomic) result += "StorageImageAtomic | ";
+    if (value & FormatFeatureFlagBits::eUniformTexelBuffer) result += "UniformTexelBuffer | ";
+    if (value & FormatFeatureFlagBits::eStorageTexelBuffer) result += "StorageTexelBuffer | ";
+    if (value & FormatFeatureFlagBits::eStorageTexelBufferAtomic) result += "StorageTexelBufferAtomic | ";
+    if (value & FormatFeatureFlagBits::eVertexBuffer) result += "VertexBuffer | ";
+    if (value & FormatFeatureFlagBits::eColorAttachment) result += "ColorAttachment | ";
+    if (value & FormatFeatureFlagBits::eColorAttachmentBlend) result += "ColorAttachmentBlend | ";
+    if (value & FormatFeatureFlagBits::eDepthStencilAttachment) result += "DepthStencilAttachment | ";
+    if (value & FormatFeatureFlagBits::eBlitSrc) result += "BlitSrc | ";
+    if (value & FormatFeatureFlagBits::eBlitDst) result += "BlitDst | ";
+    if (value & FormatFeatureFlagBits::eSampledImageFilterLinear) result += "SampledImageFilterLinear | ";
+    if (value & FormatFeatureFlagBits::eSampledImageFilterCubicIMG) result += "SampledImageFilterCubicIMG | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(QueryControlFlagBits value)
+  {
+    switch (value)
+    {
+    case QueryControlFlagBits::ePrecise: return "Precise";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(QueryControlFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & QueryControlFlagBits::ePrecise) result += "Precise | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(QueryResultFlagBits value)
+  {
+    switch (value)
+    {
+    case QueryResultFlagBits::e64: return "64";
+    case QueryResultFlagBits::eWait: return "Wait";
+    case QueryResultFlagBits::eWithAvailability: return "WithAvailability";
+    case QueryResultFlagBits::ePartial: return "Partial";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(QueryResultFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & QueryResultFlagBits::e64) result += "64 | ";
+    if (value & QueryResultFlagBits::eWait) result += "Wait | ";
+    if (value & QueryResultFlagBits::eWithAvailability) result += "WithAvailability | ";
+    if (value & QueryResultFlagBits::ePartial) result += "Partial | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(CommandBufferUsageFlagBits value)
+  {
+    switch (value)
+    {
+    case CommandBufferUsageFlagBits::eOneTimeSubmit: return "OneTimeSubmit";
+    case CommandBufferUsageFlagBits::eRenderPassContinue: return "RenderPassContinue";
+    case CommandBufferUsageFlagBits::eSimultaneousUse: return "SimultaneousUse";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CommandBufferUsageFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & CommandBufferUsageFlagBits::eOneTimeSubmit) result += "OneTimeSubmit | ";
+    if (value & CommandBufferUsageFlagBits::eRenderPassContinue) result += "RenderPassContinue | ";
+    if (value & CommandBufferUsageFlagBits::eSimultaneousUse) result += "SimultaneousUse | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(QueryPipelineStatisticFlagBits value)
+  {
+    switch (value)
+    {
+    case QueryPipelineStatisticFlagBits::eInputAssemblyVertices: return "InputAssemblyVertices";
+    case QueryPipelineStatisticFlagBits::eInputAssemblyPrimitives: return "InputAssemblyPrimitives";
+    case QueryPipelineStatisticFlagBits::eVertexShaderInvocations: return "VertexShaderInvocations";
+    case QueryPipelineStatisticFlagBits::eGeometryShaderInvocations: return "GeometryShaderInvocations";
+    case QueryPipelineStatisticFlagBits::eGeometryShaderPrimitives: return "GeometryShaderPrimitives";
+    case QueryPipelineStatisticFlagBits::eClippingInvocations: return "ClippingInvocations";
+    case QueryPipelineStatisticFlagBits::eClippingPrimitives: return "ClippingPrimitives";
+    case QueryPipelineStatisticFlagBits::eFragmentShaderInvocations: return "FragmentShaderInvocations";
+    case QueryPipelineStatisticFlagBits::eTessellationControlShaderPatches: return "TessellationControlShaderPatches";
+    case QueryPipelineStatisticFlagBits::eTessellationEvaluationShaderInvocations: return "TessellationEvaluationShaderInvocations";
+    case QueryPipelineStatisticFlagBits::eComputeShaderInvocations: return "ComputeShaderInvocations";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(QueryPipelineStatisticFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & QueryPipelineStatisticFlagBits::eInputAssemblyVertices) result += "InputAssemblyVertices | ";
+    if (value & QueryPipelineStatisticFlagBits::eInputAssemblyPrimitives) result += "InputAssemblyPrimitives | ";
+    if (value & QueryPipelineStatisticFlagBits::eVertexShaderInvocations) result += "VertexShaderInvocations | ";
+    if (value & QueryPipelineStatisticFlagBits::eGeometryShaderInvocations) result += "GeometryShaderInvocations | ";
+    if (value & QueryPipelineStatisticFlagBits::eGeometryShaderPrimitives) result += "GeometryShaderPrimitives | ";
+    if (value & QueryPipelineStatisticFlagBits::eClippingInvocations) result += "ClippingInvocations | ";
+    if (value & QueryPipelineStatisticFlagBits::eClippingPrimitives) result += "ClippingPrimitives | ";
+    if (value & QueryPipelineStatisticFlagBits::eFragmentShaderInvocations) result += "FragmentShaderInvocations | ";
+    if (value & QueryPipelineStatisticFlagBits::eTessellationControlShaderPatches) result += "TessellationControlShaderPatches | ";
+    if (value & QueryPipelineStatisticFlagBits::eTessellationEvaluationShaderInvocations) result += "TessellationEvaluationShaderInvocations | ";
+    if (value & QueryPipelineStatisticFlagBits::eComputeShaderInvocations) result += "ComputeShaderInvocations | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(ImageAspectFlagBits value)
+  {
+    switch (value)
+    {
+    case ImageAspectFlagBits::eColor: return "Color";
+    case ImageAspectFlagBits::eDepth: return "Depth";
+    case ImageAspectFlagBits::eStencil: return "Stencil";
+    case ImageAspectFlagBits::eMetadata: return "Metadata";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ImageAspectFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & ImageAspectFlagBits::eColor) result += "Color | ";
+    if (value & ImageAspectFlagBits::eDepth) result += "Depth | ";
+    if (value & ImageAspectFlagBits::eStencil) result += "Stencil | ";
+    if (value & ImageAspectFlagBits::eMetadata) result += "Metadata | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(SparseImageFormatFlagBits value)
+  {
+    switch (value)
+    {
+    case SparseImageFormatFlagBits::eSingleMiptail: return "SingleMiptail";
+    case SparseImageFormatFlagBits::eAlignedMipSize: return "AlignedMipSize";
+    case SparseImageFormatFlagBits::eNonstandardBlockSize: return "NonstandardBlockSize";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SparseImageFormatFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & SparseImageFormatFlagBits::eSingleMiptail) result += "SingleMiptail | ";
+    if (value & SparseImageFormatFlagBits::eAlignedMipSize) result += "AlignedMipSize | ";
+    if (value & SparseImageFormatFlagBits::eNonstandardBlockSize) result += "NonstandardBlockSize | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(SparseMemoryBindFlagBits value)
+  {
+    switch (value)
+    {
+    case SparseMemoryBindFlagBits::eMetadata: return "Metadata";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SparseMemoryBindFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & SparseMemoryBindFlagBits::eMetadata) result += "Metadata | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(PipelineStageFlagBits value)
+  {
+    switch (value)
+    {
+    case PipelineStageFlagBits::eTopOfPipe: return "TopOfPipe";
+    case PipelineStageFlagBits::eDrawIndirect: return "DrawIndirect";
+    case PipelineStageFlagBits::eVertexInput: return "VertexInput";
+    case PipelineStageFlagBits::eVertexShader: return "VertexShader";
+    case PipelineStageFlagBits::eTessellationControlShader: return "TessellationControlShader";
+    case PipelineStageFlagBits::eTessellationEvaluationShader: return "TessellationEvaluationShader";
+    case PipelineStageFlagBits::eGeometryShader: return "GeometryShader";
+    case PipelineStageFlagBits::eFragmentShader: return "FragmentShader";
+    case PipelineStageFlagBits::eEarlyFragmentTests: return "EarlyFragmentTests";
+    case PipelineStageFlagBits::eLateFragmentTests: return "LateFragmentTests";
+    case PipelineStageFlagBits::eColorAttachmentOutput: return "ColorAttachmentOutput";
+    case PipelineStageFlagBits::eComputeShader: return "ComputeShader";
+    case PipelineStageFlagBits::eTransfer: return "Transfer";
+    case PipelineStageFlagBits::eBottomOfPipe: return "BottomOfPipe";
+    case PipelineStageFlagBits::eHost: return "Host";
+    case PipelineStageFlagBits::eAllGraphics: return "AllGraphics";
+    case PipelineStageFlagBits::eAllCommands: return "AllCommands";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(PipelineStageFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & PipelineStageFlagBits::eTopOfPipe) result += "TopOfPipe | ";
+    if (value & PipelineStageFlagBits::eDrawIndirect) result += "DrawIndirect | ";
+    if (value & PipelineStageFlagBits::eVertexInput) result += "VertexInput | ";
+    if (value & PipelineStageFlagBits::eVertexShader) result += "VertexShader | ";
+    if (value & PipelineStageFlagBits::eTessellationControlShader) result += "TessellationControlShader | ";
+    if (value & PipelineStageFlagBits::eTessellationEvaluationShader) result += "TessellationEvaluationShader | ";
+    if (value & PipelineStageFlagBits::eGeometryShader) result += "GeometryShader | ";
+    if (value & PipelineStageFlagBits::eFragmentShader) result += "FragmentShader | ";
+    if (value & PipelineStageFlagBits::eEarlyFragmentTests) result += "EarlyFragmentTests | ";
+    if (value & PipelineStageFlagBits::eLateFragmentTests) result += "LateFragmentTests | ";
+    if (value & PipelineStageFlagBits::eColorAttachmentOutput) result += "ColorAttachmentOutput | ";
+    if (value & PipelineStageFlagBits::eComputeShader) result += "ComputeShader | ";
+    if (value & PipelineStageFlagBits::eTransfer) result += "Transfer | ";
+    if (value & PipelineStageFlagBits::eBottomOfPipe) result += "BottomOfPipe | ";
+    if (value & PipelineStageFlagBits::eHost) result += "Host | ";
+    if (value & PipelineStageFlagBits::eAllGraphics) result += "AllGraphics | ";
+    if (value & PipelineStageFlagBits::eAllCommands) result += "AllCommands | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(CommandPoolCreateFlagBits value)
+  {
+    switch (value)
+    {
+    case CommandPoolCreateFlagBits::eTransient: return "Transient";
+    case CommandPoolCreateFlagBits::eResetCommandBuffer: return "ResetCommandBuffer";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CommandPoolCreateFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & CommandPoolCreateFlagBits::eTransient) result += "Transient | ";
+    if (value & CommandPoolCreateFlagBits::eResetCommandBuffer) result += "ResetCommandBuffer | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(CommandPoolResetFlagBits value)
+  {
+    switch (value)
+    {
+    case CommandPoolResetFlagBits::eReleaseResources: return "ReleaseResources";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CommandPoolResetFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & CommandPoolResetFlagBits::eReleaseResources) result += "ReleaseResources | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(CommandBufferResetFlagBits value)
+  {
+    switch (value)
+    {
+    case CommandBufferResetFlagBits::eReleaseResources: return "ReleaseResources";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CommandBufferResetFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & CommandBufferResetFlagBits::eReleaseResources) result += "ReleaseResources | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(SampleCountFlagBits value)
+  {
+    switch (value)
+    {
+    case SampleCountFlagBits::e1: return "1";
+    case SampleCountFlagBits::e2: return "2";
+    case SampleCountFlagBits::e4: return "4";
+    case SampleCountFlagBits::e8: return "8";
+    case SampleCountFlagBits::e16: return "16";
+    case SampleCountFlagBits::e32: return "32";
+    case SampleCountFlagBits::e64: return "64";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SampleCountFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & SampleCountFlagBits::e1) result += "1 | ";
+    if (value & SampleCountFlagBits::e2) result += "2 | ";
+    if (value & SampleCountFlagBits::e4) result += "4 | ";
+    if (value & SampleCountFlagBits::e8) result += "8 | ";
+    if (value & SampleCountFlagBits::e16) result += "16 | ";
+    if (value & SampleCountFlagBits::e32) result += "32 | ";
+    if (value & SampleCountFlagBits::e64) result += "64 | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(AttachmentDescriptionFlagBits value)
+  {
+    switch (value)
+    {
+    case AttachmentDescriptionFlagBits::eMayAlias: return "MayAlias";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(AttachmentDescriptionFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & AttachmentDescriptionFlagBits::eMayAlias) result += "MayAlias | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(StencilFaceFlagBits value)
+  {
+    switch (value)
+    {
+    case StencilFaceFlagBits::eFront: return "Front";
+    case StencilFaceFlagBits::eBack: return "Back";
+    case StencilFaceFlagBits::eVkStencilFrontAndBack: return "VkStencilFrontAndBack";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(StencilFaceFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & StencilFaceFlagBits::eFront) result += "Front | ";
+    if (value & StencilFaceFlagBits::eBack) result += "Back | ";
+    if (value & StencilFaceFlagBits::eVkStencilFrontAndBack) result += "VkStencilFrontAndBack | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(DescriptorPoolCreateFlagBits value)
+  {
+    switch (value)
+    {
+    case DescriptorPoolCreateFlagBits::eFreeDescriptorSet: return "FreeDescriptorSet";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(DescriptorPoolCreateFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & DescriptorPoolCreateFlagBits::eFreeDescriptorSet) result += "FreeDescriptorSet | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(DependencyFlagBits value)
+  {
+    switch (value)
+    {
+    case DependencyFlagBits::eByRegion: return "ByRegion";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(DependencyFlags value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & DependencyFlagBits::eByRegion) result += "ByRegion | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(PresentModeKHR value)
+  {
+    switch (value)
+    {
+    case PresentModeKHR::eImmediate: return "Immediate";
+    case PresentModeKHR::eMailbox: return "Mailbox";
+    case PresentModeKHR::eFifo: return "Fifo";
+    case PresentModeKHR::eFifoRelaxed: return "FifoRelaxed";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(ColorSpaceKHR value)
+  {
+    switch (value)
+    {
+    case ColorSpaceKHR::eSrgbNonlinear: return "SrgbNonlinear";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(DisplayPlaneAlphaFlagBitsKHR value)
+  {
+    switch (value)
+    {
+    case DisplayPlaneAlphaFlagBitsKHR::eOpaque: return "Opaque";
+    case DisplayPlaneAlphaFlagBitsKHR::eGlobal: return "Global";
+    case DisplayPlaneAlphaFlagBitsKHR::ePerPixel: return "PerPixel";
+    case DisplayPlaneAlphaFlagBitsKHR::ePerPixelPremultiplied: return "PerPixelPremultiplied";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(DisplayPlaneAlphaFlagsKHR value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & DisplayPlaneAlphaFlagBitsKHR::eOpaque) result += "Opaque | ";
+    if (value & DisplayPlaneAlphaFlagBitsKHR::eGlobal) result += "Global | ";
+    if (value & DisplayPlaneAlphaFlagBitsKHR::ePerPixel) result += "PerPixel | ";
+    if (value & DisplayPlaneAlphaFlagBitsKHR::ePerPixelPremultiplied) result += "PerPixelPremultiplied | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(CompositeAlphaFlagBitsKHR value)
+  {
+    switch (value)
+    {
+    case CompositeAlphaFlagBitsKHR::eOpaque: return "Opaque";
+    case CompositeAlphaFlagBitsKHR::ePreMultiplied: return "PreMultiplied";
+    case CompositeAlphaFlagBitsKHR::ePostMultiplied: return "PostMultiplied";
+    case CompositeAlphaFlagBitsKHR::eInherit: return "Inherit";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(CompositeAlphaFlagsKHR value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & CompositeAlphaFlagBitsKHR::eOpaque) result += "Opaque | ";
+    if (value & CompositeAlphaFlagBitsKHR::ePreMultiplied) result += "PreMultiplied | ";
+    if (value & CompositeAlphaFlagBitsKHR::ePostMultiplied) result += "PostMultiplied | ";
+    if (value & CompositeAlphaFlagBitsKHR::eInherit) result += "Inherit | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(SurfaceTransformFlagBitsKHR value)
+  {
+    switch (value)
+    {
+    case SurfaceTransformFlagBitsKHR::eIdentity: return "Identity";
+    case SurfaceTransformFlagBitsKHR::eRotate90: return "Rotate90";
+    case SurfaceTransformFlagBitsKHR::eRotate180: return "Rotate180";
+    case SurfaceTransformFlagBitsKHR::eRotate270: return "Rotate270";
+    case SurfaceTransformFlagBitsKHR::eHorizontalMirror: return "HorizontalMirror";
+    case SurfaceTransformFlagBitsKHR::eHorizontalMirrorRotate90: return "HorizontalMirrorRotate90";
+    case SurfaceTransformFlagBitsKHR::eHorizontalMirrorRotate180: return "HorizontalMirrorRotate180";
+    case SurfaceTransformFlagBitsKHR::eHorizontalMirrorRotate270: return "HorizontalMirrorRotate270";
+    case SurfaceTransformFlagBitsKHR::eInherit: return "Inherit";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(SurfaceTransformFlagsKHR value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & SurfaceTransformFlagBitsKHR::eIdentity) result += "Identity | ";
+    if (value & SurfaceTransformFlagBitsKHR::eRotate90) result += "Rotate90 | ";
+    if (value & SurfaceTransformFlagBitsKHR::eRotate180) result += "Rotate180 | ";
+    if (value & SurfaceTransformFlagBitsKHR::eRotate270) result += "Rotate270 | ";
+    if (value & SurfaceTransformFlagBitsKHR::eHorizontalMirror) result += "HorizontalMirror | ";
+    if (value & SurfaceTransformFlagBitsKHR::eHorizontalMirrorRotate90) result += "HorizontalMirrorRotate90 | ";
+    if (value & SurfaceTransformFlagBitsKHR::eHorizontalMirrorRotate180) result += "HorizontalMirrorRotate180 | ";
+    if (value & SurfaceTransformFlagBitsKHR::eHorizontalMirrorRotate270) result += "HorizontalMirrorRotate270 | ";
+    if (value & SurfaceTransformFlagBitsKHR::eInherit) result += "Inherit | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(DebugReportFlagBitsEXT value)
+  {
+    switch (value)
+    {
+    case DebugReportFlagBitsEXT::eInformation: return "Information";
+    case DebugReportFlagBitsEXT::eWarning: return "Warning";
+    case DebugReportFlagBitsEXT::ePerformanceWarning: return "PerformanceWarning";
+    case DebugReportFlagBitsEXT::eError: return "Error";
+    case DebugReportFlagBitsEXT::eDebug: return "Debug";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(DebugReportFlagsEXT value)
+  {
+    if (!value) return "{}";
+    std::string result;
+    if (value & DebugReportFlagBitsEXT::eInformation) result += "Information | ";
+    if (value & DebugReportFlagBitsEXT::eWarning) result += "Warning | ";
+    if (value & DebugReportFlagBitsEXT::ePerformanceWarning) result += "PerformanceWarning | ";
+    if (value & DebugReportFlagBitsEXT::eError) result += "Error | ";
+    if (value & DebugReportFlagBitsEXT::eDebug) result += "Debug | ";
+    return "{" + result.substr(0, result.size() - 3) + "}";
+  }
+
+  inline std::string to_string(DebugReportObjectTypeEXT value)
+  {
+    switch (value)
+    {
+    case DebugReportObjectTypeEXT::eUnknown: return "Unknown";
+    case DebugReportObjectTypeEXT::eInstance: return "Instance";
+    case DebugReportObjectTypeEXT::ePhysicalDevice: return "PhysicalDevice";
+    case DebugReportObjectTypeEXT::eDevice: return "Device";
+    case DebugReportObjectTypeEXT::eQueue: return "Queue";
+    case DebugReportObjectTypeEXT::eSemaphore: return "Semaphore";
+    case DebugReportObjectTypeEXT::eCommandBuffer: return "CommandBuffer";
+    case DebugReportObjectTypeEXT::eFence: return "Fence";
+    case DebugReportObjectTypeEXT::eDeviceMemory: return "DeviceMemory";
+    case DebugReportObjectTypeEXT::eBuffer: return "Buffer";
+    case DebugReportObjectTypeEXT::eImage: return "Image";
+    case DebugReportObjectTypeEXT::eEvent: return "Event";
+    case DebugReportObjectTypeEXT::eQueryPool: return "QueryPool";
+    case DebugReportObjectTypeEXT::eBufferView: return "BufferView";
+    case DebugReportObjectTypeEXT::eImageView: return "ImageView";
+    case DebugReportObjectTypeEXT::eShaderModule: return "ShaderModule";
+    case DebugReportObjectTypeEXT::ePipelineCache: return "PipelineCache";
+    case DebugReportObjectTypeEXT::ePipelineLayout: return "PipelineLayout";
+    case DebugReportObjectTypeEXT::eRenderPass: return "RenderPass";
+    case DebugReportObjectTypeEXT::ePipeline: return "Pipeline";
+    case DebugReportObjectTypeEXT::eDescriptorSetLayout: return "DescriptorSetLayout";
+    case DebugReportObjectTypeEXT::eSampler: return "Sampler";
+    case DebugReportObjectTypeEXT::eDescriptorPool: return "DescriptorPool";
+    case DebugReportObjectTypeEXT::eDescriptorSet: return "DescriptorSet";
+    case DebugReportObjectTypeEXT::eFramebuffer: return "Framebuffer";
+    case DebugReportObjectTypeEXT::eCommandPool: return "CommandPool";
+    case DebugReportObjectTypeEXT::eSurfaceKhr: return "SurfaceKhr";
+    case DebugReportObjectTypeEXT::eSwapchainKhr: return "SwapchainKhr";
+    case DebugReportObjectTypeEXT::eDebugReport: return "DebugReport";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(DebugReportErrorEXT value)
+  {
+    switch (value)
+    {
+    case DebugReportErrorEXT::eNone: return "None";
+    case DebugReportErrorEXT::eCallbackRef: return "CallbackRef";
+    default: return "invalid";
+    }
+  }
+
+  inline std::string to_string(RasterizationOrderAMD value)
+  {
+    switch (value)
+    {
+    case RasterizationOrderAMD::eStrict: return "Strict";
+    case RasterizationOrderAMD::eRelaxed: return "Relaxed";
+    default: return "invalid";
+    }
+  }
+
+} // namespace vk
+
+#endif
diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt
index acf67b8..9d6705b 100644
--- a/layers/CMakeLists.txt
+++ b/layers/CMakeLists.txt
@@ -28,7 +28,6 @@
     VkLayer_parameter_validation
     VkLayer_swapchain
     VkLayer_threading
-    VkLayer_device_limits
     )
 
 if (WIN32)
@@ -105,7 +104,7 @@
 endif()
 
 add_custom_command(OUTPUT vk_dispatch_table_helper.h
-    COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/vk-generate.py ${DisplayServer} dispatch-table-ops layer > vk_dispatch_table_helper.h
+    COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/vk-generate.py AllPlatforms dispatch-table-ops layer > vk_dispatch_table_helper.h
     DEPENDS ${PROJECT_SOURCE_DIR}/vk-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py)
 
 run_vk_helper(gen_enum_string_helper vk_enum_string_helper.h)
@@ -137,7 +136,6 @@
     vk_safe_struct.cpp
 )
 
-run_vk_layer_generate(object_tracker object_tracker.cpp)
 run_vk_layer_xml_generate(Threading thread_check.h)
 run_vk_layer_generate(unique_objects unique_objects.cpp)
 run_vk_layer_xml_generate(ParamChecker parameter_validation.h)
@@ -153,11 +151,10 @@
 endif()
 
 add_vk_layer(core_validation core_validation.cpp vk_layer_table.cpp vk_safe_struct.cpp descriptor_sets.cpp)
-add_vk_layer(device_limits device_limits.cpp vk_layer_table.cpp)
+add_vk_layer(object_tracker object_tracker.cpp vk_layer_table.cpp)
 add_vk_layer(image image.cpp vk_layer_table.cpp)
 add_vk_layer(swapchain swapchain.cpp vk_layer_table.cpp)
 # generated
-add_vk_layer(object_tracker object_tracker.cpp vk_layer_table.cpp)
 add_vk_layer(threading threading.cpp thread_check.h vk_layer_table.cpp)
 add_vk_layer(unique_objects unique_objects.cpp vk_layer_table.cpp vk_safe_struct.cpp)
 add_vk_layer(parameter_validation parameter_validation.cpp parameter_validation.h vk_layer_table.cpp)
diff --git a/layers/README.md b/layers/README.md
index e2cea90..0aa1cff 100644
--- a/layers/README.md
+++ b/layers/README.md
@@ -20,12 +20,14 @@
 vkXXXXGetProcAddr is used internally by the Layers and Loader to initialize dispatch tables.
 Layers can also be activated via the VK_INSTANCE_LAYERS environment variable.
 
-All validation layers work with the DEBUG_REPORT extension to provide the application or user with
-validation feedback. When a validation layer is enabled, it will look at the vk_layer_settings.txt
-file to determine its behavior. Such as outputing to a file, stdout or debug output (Windows). An
-application can also register callback functions via the DEBUG_REPORT extension to receive callbacks
-when the requested validation events happen. Application callbacks happen regardless of the
-settings in the vk_layer_settings.txt file.
+All validation layers work with the DEBUG_REPORT extension to provide validation feedback.
+When a validation layer is enabled, it will look for a vk_layer_settings.txt file to define
+its loggin behavior, which can include sending output to a file, stdout, or debug output (Windows).
+Applications can also register debug callback functions via the DEBUG_REPORT extension to receive
+callbacks when validation events occur. Application callbacks are independent of settings in a
+vk_layer_settings.txt file which will be carried out separately. If no vk_layer_settings.txt
+file is present and no application callbacks are registered, error messages will be output
+through default logging callbacks.
 
 ### Layer library example code
 
@@ -37,7 +39,7 @@
 For complete details of current validation layers, including all of the validation checks that they perform, please refer to the document `layers/vk_validation_layer_details.md`. Below is a brief overview of each layer.
 
 ### Standard Validation
-This is a meta-layer managed by the loader. (name = `VK_LAYER_LUNARG_standard_validation`) - specifying this layer name will cause the loader to load the all of the standard validation layers (listed below) in the following optimal order:  `VK_LAYER_GOOGLE_threading`, `VK_LAYER_LUNARG_parameter_validation`, `VK_LAYER_LUNARG_device_limits`, `VK_LAYER_LUNARG_object_tracker`, `VK_LAYER_LUNARG_image`, `VK_LAYER_LUNARG_core_validation`,` VK_LAYER_LUNARG_swapchain`, and `VK_LAYER_GOOGLE_unique_objects`. Other layers can be specified and the loader will remove duplicates.
+This is a meta-layer managed by the loader. (name = `VK_LAYER_LUNARG_standard_validation`) - specifying this layer name will cause the loader to load the all of the standard validation layers (listed below) in the following optimal order:  `VK_LAYER_GOOGLE_threading`, `VK_LAYER_LUNARG_parameter_validation`, `VK_LAYER_LUNARG_object_tracker`, `VK_LAYER_LUNARG_image`, `VK_LAYER_LUNARG_core_validation`,` VK_LAYER_LUNARG_swapchain`, and `VK_LAYER_GOOGLE_unique_objects`. Other layers can be specified and the loader will remove duplicates.
 
 ### Object Validation and Statistics
 (build dir)/layers/object_tracker.cpp (name=`VK_LAYER_LUNARG_object_tracker`) - Track object creation, use, and destruction. As objects are created they are stored in a map. As objects are used the layer verifies they exist in the map, flagging errors for unknown objects. As objects are destroyed they are removed from the map. At `vkDestroyDevice()` and `vkDestroyInstance()` times, if any objects have not been destroyed they are reported as leaked objects. If a Dbg callback function is registered this layer will use callback function(s) for reporting, otherwise it will use stdout.
@@ -57,9 +59,6 @@
 ### Swapchain
 layers/swapchain.cpp (name=`VK_LAYER_LUNARG_swapchain`) - Check that WSI extensions are being used correctly.
 
-### Device Limitations
-layers/device_limits.cpp (name=`VK_LAYER_LUNARG_device_limits`) - This layer is intended to capture underlying device features and limitations and then flag errors if an app makes requests for unsupported features or exceeding limitations. This layer is a work in progress and currently only flags some high-level errors without flagging errors on specific feature and limitation. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout.
-
 ### Unique Objects
 (build dir)/layers/unique_objects.cpp (name=`VK_LAYER_GOOGLE_unique_objects`) - The Vulkan specification allows objects that have non-unique handles. This makes tracking object lifetimes difficult in that it is unclear which object is being referenced on deletion. The unique_objects layer was created to address this problem. If loaded in the correct position (last, which is closest to the display driver) it will alias all objects with a unique object representation, allowing proper object lifetime tracking. This layer does no validation on its own and may not be required for the proper operation of all layers or all platforms. One sign that it is needed is the appearance of errors emitted from the object_tracker layer indicating the use of previously destroyed objects.
 
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index e0d04c2..bb10a39 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -38,6 +38,7 @@
 #include <map>
 #include <mutex>
 #include <set>
+//#include <memory>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -93,16 +94,9 @@
 // Object value will be used to identify them internally.
 static const VkDeviceMemory MEMTRACKER_SWAP_CHAIN_IMAGE_KEY = (VkDeviceMemory)(-1);
 
-// Track command pools and their command buffers
-struct CMD_POOL_INFO {
-    VkCommandPoolCreateFlags createFlags;
-    uint32_t queueFamilyIndex;
-    list<VkCommandBuffer> commandBuffers; // list container of cmd buffers allocated from this pool
-};
-
 struct devExts {
     bool wsi_enabled;
-    unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> swapchainMap;
+    unordered_map<VkSwapchainKHR, unique_ptr<SWAPCHAIN_NODE>> swapchainMap;
     unordered_map<VkImage, VkSwapchainKHR> imageToSwapchainMap;
 };
 
@@ -112,6 +106,8 @@
 // TODO : Split this into separate structs for instance and device level data?
 struct layer_data {
     VkInstance instance;
+    unique_ptr<INSTANCE_STATE> instance_state;
+
 
     debug_report_data *report_data;
     std::vector<VkDebugReportCallbackEXT> logging_callback;
@@ -119,22 +115,24 @@
     VkLayerInstanceDispatchTable *instance_dispatch_table;
 
     devExts device_extensions;
-    unordered_set<VkQueue> queues;  // all queues under given device
+    unordered_set<VkQueue> queues;  // All queues under given device
+    // Vector indices correspond to queueFamilyIndex
+    vector<unique_ptr<VkQueueFamilyProperties>> queue_family_properties;
     // Global set of all cmdBuffers that are inFlight on this device
     unordered_set<VkCommandBuffer> globalInFlightCmdBuffers;
     // Layer specific data
     unordered_map<VkSampler, unique_ptr<SAMPLER_NODE>> samplerMap;
-    unordered_map<VkImageView, VkImageViewCreateInfo> imageViewMap;
-    unordered_map<VkImage, IMAGE_NODE> imageMap;
-    unordered_map<VkBufferView, VkBufferViewCreateInfo> bufferViewMap;
-    unordered_map<VkBuffer, BUFFER_NODE> bufferMap;
+    unordered_map<VkImageView, unique_ptr<VkImageViewCreateInfo>> imageViewMap;
+    unordered_map<VkImage, unique_ptr<IMAGE_NODE>> imageMap;
+    unordered_map<VkBufferView, unique_ptr<VkBufferViewCreateInfo>> bufferViewMap;
+    unordered_map<VkBuffer, unique_ptr<BUFFER_NODE>> bufferMap;
     unordered_map<VkPipeline, PIPELINE_NODE *> pipelineMap;
-    unordered_map<VkCommandPool, CMD_POOL_INFO> commandPoolMap;
+    unordered_map<VkCommandPool, COMMAND_POOL_NODE> commandPoolMap;
     unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> descriptorPoolMap;
     unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> setMap;
     unordered_map<VkDescriptorSetLayout, cvdescriptorset::DescriptorSetLayout *> descriptorSetLayoutMap;
     unordered_map<VkPipelineLayout, PIPELINE_LAYOUT_NODE> pipelineLayoutMap;
-    unordered_map<VkDeviceMemory, DEVICE_MEM_INFO> memObjMap;
+    unordered_map<VkDeviceMemory, unique_ptr<DEVICE_MEM_INFO>> memObjMap;
     unordered_map<VkFence, FENCE_NODE> fenceMap;
     unordered_map<VkQueue, QUEUE_NODE> queueMap;
     unordered_map<VkEvent, EVENT_NODE> eventMap;
@@ -142,7 +140,7 @@
     unordered_map<VkQueryPool, QUERY_POOL_NODE> queryPoolMap;
     unordered_map<VkSemaphore, SEMAPHORE_NODE> semaphoreMap;
     unordered_map<VkCommandBuffer, GLOBAL_CB_NODE *> commandBufferMap;
-    unordered_map<VkFramebuffer, FRAMEBUFFER_NODE> frameBufferMap;
+    unordered_map<VkFramebuffer, unique_ptr<FRAMEBUFFER_NODE>> frameBufferMap;
     unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap;
     unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap;
     unordered_map<VkRenderPass, RENDER_PASS_NODE *> renderPassMap;
@@ -152,10 +150,13 @@
     // Device specific data
     PHYS_DEV_PROPERTIES_NODE phys_dev_properties;
     VkPhysicalDeviceMemoryProperties phys_dev_mem_props;
+    VkPhysicalDeviceFeatures physical_device_features;
+    unique_ptr<PHYSICAL_DEVICE_STATE> physical_device_state;
 
     layer_data()
-        : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), device_extensions(),
-          device(VK_NULL_HANDLE), phys_dev_properties{}, phys_dev_mem_props{} {};
+        : instance_state(nullptr), report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr),
+          device_extensions(), device(VK_NULL_HANDLE), phys_dev_properties{}, phys_dev_mem_props{}, physical_device_features{},
+          physical_device_state(nullptr){};
 };
 
 // TODO : Do we need to guard access to layer_data_map w/ lock?
@@ -261,18 +262,123 @@
 // TODO : This can be much smarter, using separate locks for separate global data
 static std::mutex global_lock;
 
+// Return ImageViewCreateInfo ptr for specified imageView or else NULL
+VkImageViewCreateInfo *getImageViewData(const layer_data *dev_data, VkImageView image_view) {
+    auto iv_it = dev_data->imageViewMap.find(image_view);
+    if (iv_it == dev_data->imageViewMap.end()) {
+        return nullptr;
+    }
+    return iv_it->second.get();
+}
+// Return sampler node ptr for specified sampler or else NULL
+SAMPLER_NODE *getSamplerNode(const layer_data *dev_data, VkSampler sampler) {
+    auto sampler_it = dev_data->samplerMap.find(sampler);
+    if (sampler_it == dev_data->samplerMap.end()) {
+        return nullptr;
+    }
+    return sampler_it->second.get();
+}
+// Return image node ptr for specified image or else NULL
+IMAGE_NODE *getImageNode(const layer_data *dev_data, VkImage image) {
+    auto img_it = dev_data->imageMap.find(image);
+    if (img_it == dev_data->imageMap.end()) {
+        return nullptr;
+    }
+    return img_it->second.get();
+}
+// Return buffer node ptr for specified buffer or else NULL
+BUFFER_NODE *getBufferNode(const layer_data *dev_data, VkBuffer buffer) {
+    auto buff_it = dev_data->bufferMap.find(buffer);
+    if (buff_it == dev_data->bufferMap.end()) {
+        return nullptr;
+    }
+    return buff_it->second.get();
+}
+// Return swapchain node for specified swapchain or else NULL
+SWAPCHAIN_NODE *getSwapchainNode(const layer_data *dev_data, VkSwapchainKHR swapchain) {
+    auto swp_it = dev_data->device_extensions.swapchainMap.find(swapchain);
+    if (swp_it == dev_data->device_extensions.swapchainMap.end()) {
+        return nullptr;
+    }
+    return swp_it->second.get();
+}
+// Return swapchain for specified image or else NULL
+VkSwapchainKHR getSwapchainFromImage(const layer_data *dev_data, VkImage image) {
+    auto img_it = dev_data->device_extensions.imageToSwapchainMap.find(image);
+    if (img_it == dev_data->device_extensions.imageToSwapchainMap.end()) {
+        return VK_NULL_HANDLE;
+    }
+    return img_it->second;
+}
+// Return buffer node ptr for specified buffer or else NULL
+VkBufferViewCreateInfo *getBufferViewInfo(const layer_data *my_data, VkBufferView buffer_view) {
+    auto bv_it = my_data->bufferViewMap.find(buffer_view);
+    if (bv_it == my_data->bufferViewMap.end()) {
+        return nullptr;
+    }
+    return bv_it->second.get();
+}
+
+FENCE_NODE *getFenceNode(layer_data *dev_data, VkFence fence) {
+    auto it = dev_data->fenceMap.find(fence);
+    if (it == dev_data->fenceMap.end()) {
+        return nullptr;
+    }
+    return &it->second;
+}
+
+EVENT_NODE *getEventNode(layer_data *dev_data, VkEvent event) {
+    auto it = dev_data->eventMap.find(event);
+    if (it == dev_data->eventMap.end()) {
+        return nullptr;
+    }
+    return &it->second;
+}
+
+QUERY_POOL_NODE *getQueryPoolNode(layer_data *dev_data, VkQueryPool query_pool) {
+    auto it = dev_data->queryPoolMap.find(query_pool);
+    if (it == dev_data->queryPoolMap.end()) {
+        return nullptr;
+    }
+    return &it->second;
+}
+
+QUEUE_NODE *getQueueNode(layer_data *dev_data, VkQueue queue) {
+    auto it = dev_data->queueMap.find(queue);
+    if (it == dev_data->queueMap.end()) {
+        return nullptr;
+    }
+    return &it->second;
+}
+
+SEMAPHORE_NODE *getSemaphoreNode(layer_data *dev_data, VkSemaphore semaphore) {
+    auto it = dev_data->semaphoreMap.find(semaphore);
+    if (it == dev_data->semaphoreMap.end()) {
+        return nullptr;
+    }
+    return &it->second;
+}
+
+COMMAND_POOL_NODE *getCommandPoolNode(layer_data *dev_data, VkCommandPool pool) {
+    auto it = dev_data->commandPoolMap.find(pool);
+    if (it == dev_data->commandPoolMap.end()) {
+        return nullptr;
+    }
+    return &it->second;
+}
+
 static VkDeviceMemory *get_object_mem_binding(layer_data *my_data, uint64_t handle, VkDebugReportObjectTypeEXT type) {
     switch (type) {
     case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
-        auto it = my_data->imageMap.find(VkImage(handle));
-        if (it != my_data->imageMap.end())
-            return &(*it).second.mem;
+        auto img_node = getImageNode(my_data, VkImage(handle));
+        if (img_node)
+            return &img_node->mem;
         break;
     }
     case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
-        auto it = my_data->bufferMap.find(VkBuffer(handle));
-        if (it != my_data->bufferMap.end())
-            return &(*it).second.mem;
+        auto buff_node = getBufferNode(my_data, VkBuffer(handle));
+        if (buff_node)
+            return &buff_node->mem;
         break;
     }
     default:
@@ -292,88 +398,69 @@
                                      uint64_t obj_handle, VkDebugReportObjectTypeEXT obj_type, char const *ty_str,
                                      char const *func_name, char const *usage_str) {
     bool correct_usage = false;
-    bool skipCall = false;
+    bool skip_call = false;
     if (strict)
         correct_usage = ((actual & desired) == desired);
     else
         correct_usage = ((actual & desired) != 0);
     if (!correct_usage) {
-        skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, obj_type, obj_handle, __LINE__,
-                           MEMTRACK_INVALID_USAGE_FLAG, "MEM", "Invalid usage flag for %s 0x%" PRIxLEAST64
-                                                               " used by %s. In this case, %s should have %s set during creation.",
-                           ty_str, obj_handle, func_name, ty_str, usage_str);
+        skip_call = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, obj_type, obj_handle, __LINE__,
+                            MEMTRACK_INVALID_USAGE_FLAG, "MEM", "Invalid usage flag for %s 0x%" PRIxLEAST64
+                                                                " used by %s. In this case, %s should have %s set during creation.",
+                            ty_str, obj_handle, func_name, ty_str, usage_str);
     }
-    return skipCall;
-}
-
-// Helper function to validate usage flags for images
-// Pulls image info and then sends actual vs. desired usage off to helper above where
-//  an error will be flagged if usage is not correct
-static bool validate_image_usage_flags(layer_data *dev_data, VkImage image, VkFlags desired, VkBool32 strict,
-                                           char const *func_name, char const *usage_string) {
-    bool skipCall = false;
-    auto const image_node = dev_data->imageMap.find(image);
-    if (image_node != dev_data->imageMap.end()) {
-        skipCall = validate_usage_flags(dev_data, image_node->second.createInfo.usage, desired, strict, (uint64_t)image,
-                                        VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "image", func_name, usage_string);
-    }
-    return skipCall;
+    return skip_call;
 }
 
 // Helper function to validate usage flags for buffers
-// Pulls buffer info and then sends actual vs. desired usage off to helper above where
+// For given buffer_node send actual vs. desired usage off to helper above where
 //  an error will be flagged if usage is not correct
-static bool validate_buffer_usage_flags(layer_data *dev_data, VkBuffer buffer, VkFlags desired, VkBool32 strict,
-                                            char const *func_name, char const *usage_string) {
-    bool skipCall = false;
-    auto const buffer_node = dev_data->bufferMap.find(buffer);
-    if (buffer_node != dev_data->bufferMap.end()) {
-        skipCall = validate_usage_flags(dev_data, buffer_node->second.createInfo.usage, desired, strict, (uint64_t)buffer,
-                                        VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "buffer", func_name, usage_string);
-    }
-    return skipCall;
+static bool ValidateImageUsageFlags(layer_data *dev_data, IMAGE_NODE const *image_node, VkFlags desired, VkBool32 strict,
+                                    char const *func_name, char const *usage_string) {
+    return validate_usage_flags(dev_data, image_node->createInfo.usage, desired, strict,
+                                reinterpret_cast<const uint64_t &>(image_node->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                                "image", func_name, usage_string);
+}
+
+// Helper function to validate usage flags for buffers
+// For given buffer_node send actual vs. desired usage off to helper above where
+//  an error will be flagged if usage is not correct
+static bool ValidateBufferUsageFlags(layer_data *dev_data, BUFFER_NODE const *buffer_node, VkFlags desired, VkBool32 strict,
+                                     char const *func_name, char const *usage_string) {
+    return validate_usage_flags(dev_data, buffer_node->createInfo.usage, desired, strict,
+                                reinterpret_cast<const uint64_t &>(buffer_node->buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
+                                "buffer", func_name, usage_string);
 }
 
 // Return ptr to info in map container containing mem, or NULL if not found
 //  Calls to this function should be wrapped in mutex
-static DEVICE_MEM_INFO *get_mem_obj_info(layer_data *dev_data, const VkDeviceMemory mem) {
-    auto item = dev_data->memObjMap.find(mem);
-    if (item != dev_data->memObjMap.end()) {
-        return &(*item).second;
-    } else {
+DEVICE_MEM_INFO *getMemObjInfo(const layer_data *dev_data, const VkDeviceMemory mem) {
+    auto mem_it = dev_data->memObjMap.find(mem);
+    if (mem_it == dev_data->memObjMap.end()) {
         return NULL;
     }
+    return mem_it->second.get();
 }
 
 static void add_mem_obj_info(layer_data *my_data, void *object, const VkDeviceMemory mem,
                              const VkMemoryAllocateInfo *pAllocateInfo) {
     assert(object != NULL);
 
-    memcpy(&my_data->memObjMap[mem].allocInfo, pAllocateInfo, sizeof(VkMemoryAllocateInfo));
-    // TODO:  Update for real hardware, actually process allocation info structures
-    my_data->memObjMap[mem].allocInfo.pNext = NULL;
-    my_data->memObjMap[mem].object = object;
-    my_data->memObjMap[mem].mem = mem;
-    my_data->memObjMap[mem].image = VK_NULL_HANDLE;
-    my_data->memObjMap[mem].memRange.offset = 0;
-    my_data->memObjMap[mem].memRange.size = 0;
-    my_data->memObjMap[mem].pData = 0;
-    my_data->memObjMap[mem].pDriverData = 0;
-    my_data->memObjMap[mem].valid = false;
+    my_data->memObjMap[mem] = unique_ptr<DEVICE_MEM_INFO>(new DEVICE_MEM_INFO(object, mem, pAllocateInfo));
 }
 
 static bool validate_memory_is_valid(layer_data *dev_data, VkDeviceMemory mem, const char *functionName,
                                      VkImage image = VK_NULL_HANDLE) {
     if (mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
-        auto const image_node = dev_data->imageMap.find(image);
-        if (image_node != dev_data->imageMap.end() && !image_node->second.valid) {
+        auto const image_node = getImageNode(dev_data, image);
+        if (image_node && !image_node->valid) {
             return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                            (uint64_t)(mem), __LINE__, MEMTRACK_INVALID_USAGE_FLAG, "MEM",
                            "%s: Cannot read invalid swapchain image 0x%" PRIx64 ", please fill the memory before using.",
                            functionName, (uint64_t)(image));
         }
     } else {
-        DEVICE_MEM_INFO *pMemObj = get_mem_obj_info(dev_data, mem);
+        DEVICE_MEM_INFO *pMemObj = getMemObjInfo(dev_data, mem);
         if (pMemObj && !pMemObj->valid) {
             return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                            (uint64_t)(mem), __LINE__, MEMTRACK_INVALID_USAGE_FLAG, "MEM",
@@ -386,12 +473,12 @@
 
 static void set_memory_valid(layer_data *dev_data, VkDeviceMemory mem, bool valid, VkImage image = VK_NULL_HANDLE) {
     if (mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
-        auto image_node = dev_data->imageMap.find(image);
-        if (image_node != dev_data->imageMap.end()) {
-            image_node->second.valid = valid;
+        auto image_node = getImageNode(dev_data, image);
+        if (image_node) {
+            image_node->valid = valid;
         }
     } else {
-        DEVICE_MEM_INFO *pMemObj = get_mem_obj_info(dev_data, mem);
+        DEVICE_MEM_INFO *pMemObj = getMemObjInfo(dev_data, mem);
         if (pMemObj) {
             pMemObj->valid = valid;
         }
@@ -402,15 +489,15 @@
 // Find Mem Obj Info and add CB reference to list container
 static bool update_cmd_buf_and_mem_references(layer_data *dev_data, const VkCommandBuffer cb, const VkDeviceMemory mem,
                                               const char *apiName) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     // Skip validation if this image was created through WSI
     if (mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
 
         // First update CB binding in MemObj mini CB list
-        DEVICE_MEM_INFO *pMemInfo = get_mem_obj_info(dev_data, mem);
+        DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, mem);
         if (pMemInfo) {
-            pMemInfo->commandBufferBindings.insert(cb);
+            pMemInfo->command_buffer_bindings.insert(cb);
             // Now update CBInfo's Mem reference list
             GLOBAL_CB_NODE *pCBNode = getCBNode(dev_data, cb);
             // TODO: keep track of all destroyed CBs so we know if this is a stale or simply invalid object
@@ -419,16 +506,55 @@
             }
         }
     }
-    return skipCall;
+    return skip_call;
 }
+
+// Create binding link between given iamge node and command buffer node
+static bool addCommandBufferBindingImage(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_NODE *img_node, const char *apiName) {
+    bool skip_call = false;
+    // Skip validation if this image was created through WSI
+    if (img_node->mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
+        // First update CB binding in MemObj mini CB list
+        DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, img_node->mem);
+        if (pMemInfo) {
+            pMemInfo->command_buffer_bindings.insert(cb_node->commandBuffer);
+            // Now update CBInfo's Mem reference list
+            cb_node->memObjs.insert(img_node->mem);
+        }
+        cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(img_node->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT});
+    }
+    // Now update cb binding for image
+    img_node->cb_bindings.insert(cb_node);
+    return skip_call;
+}
+
+// Create binding link between given buffer node and command buffer node
+static bool addCommandBufferBindingBuffer(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, BUFFER_NODE *buff_node,
+                                          const char *apiName) {
+    bool skip_call = false;
+
+    // First update CB binding in MemObj mini CB list
+    DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, buff_node->mem);
+    if (pMemInfo) {
+        pMemInfo->command_buffer_bindings.insert(cb_node->commandBuffer);
+        // Now update CBInfo's Mem reference list
+        cb_node->memObjs.insert(buff_node->mem);
+        cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(buff_node->buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT});
+    }
+    // Now update cb binding for buffer
+    buff_node->cb_bindings.insert(cb_node);
+
+    return skip_call;
+}
+
 // For every mem obj bound to particular CB, free bindings related to that CB
 static void clear_cmd_buf_and_mem_references(layer_data *dev_data, GLOBAL_CB_NODE *pCBNode) {
     if (pCBNode) {
         if (pCBNode->memObjs.size() > 0) {
             for (auto mem : pCBNode->memObjs) {
-                DEVICE_MEM_INFO *pInfo = get_mem_obj_info(dev_data, mem);
+                DEVICE_MEM_INFO *pInfo = getMemObjInfo(dev_data, mem);
                 if (pInfo) {
-                    pInfo->commandBufferBindings.erase(pCBNode->commandBuffer);
+                    pInfo->command_buffer_bindings.erase(pCBNode->commandBuffer);
                 }
             }
             pCBNode->memObjs.clear();
@@ -443,89 +569,77 @@
 
 // For given MemObjInfo, report Obj & CB bindings
 static bool reportMemReferencesAndCleanUp(layer_data *dev_data, DEVICE_MEM_INFO *pMemObjInfo) {
-    bool skipCall = false;
-    size_t cmdBufRefCount = pMemObjInfo->commandBufferBindings.size();
-    size_t objRefCount = pMemObjInfo->objBindings.size();
+    bool skip_call = false;
+    size_t cmdBufRefCount = pMemObjInfo->command_buffer_bindings.size();
+    size_t objRefCount = pMemObjInfo->obj_bindings.size();
 
-    if ((pMemObjInfo->commandBufferBindings.size()) != 0) {
-        skipCall = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                           (uint64_t)pMemObjInfo->mem, __LINE__, MEMTRACK_FREED_MEM_REF, "MEM",
-                           "Attempting to free memory object 0x%" PRIxLEAST64 " which still contains " PRINTF_SIZE_T_SPECIFIER
-                           " references",
-                           (uint64_t)pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
+    if ((pMemObjInfo->command_buffer_bindings.size()) != 0) {
+        skip_call = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            (uint64_t)pMemObjInfo->mem, __LINE__, MEMTRACK_FREED_MEM_REF, "MEM",
+                            "Attempting to free memory object 0x%" PRIxLEAST64 " which still contains " PRINTF_SIZE_T_SPECIFIER
+                            " references",
+                            (uint64_t)pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
     }
 
-    if (cmdBufRefCount > 0 && pMemObjInfo->commandBufferBindings.size() > 0) {
-        for (auto cb : pMemObjInfo->commandBufferBindings) {
+    if (cmdBufRefCount > 0 && pMemObjInfo->command_buffer_bindings.size() > 0) {
+        for (auto cb : pMemObjInfo->command_buffer_bindings) {
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                     (uint64_t)cb, __LINE__, MEMTRACK_FREED_MEM_REF, "MEM",
                     "Command Buffer 0x%p still has a reference to mem obj 0x%" PRIxLEAST64, cb, (uint64_t)pMemObjInfo->mem);
         }
         // Clear the list of hanging references
-        pMemObjInfo->commandBufferBindings.clear();
+        pMemObjInfo->command_buffer_bindings.clear();
     }
 
-    if (objRefCount > 0 && pMemObjInfo->objBindings.size() > 0) {
-        for (auto obj : pMemObjInfo->objBindings) {
+    if (objRefCount > 0 && pMemObjInfo->obj_bindings.size() > 0) {
+        for (auto obj : pMemObjInfo->obj_bindings) {
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, obj.type, obj.handle, __LINE__,
                     MEMTRACK_FREED_MEM_REF, "MEM", "VK Object 0x%" PRIxLEAST64 " still has a reference to mem obj 0x%" PRIxLEAST64,
                     obj.handle, (uint64_t)pMemObjInfo->mem);
         }
         // Clear the list of hanging references
-        pMemObjInfo->objBindings.clear();
+        pMemObjInfo->obj_bindings.clear();
     }
-    return skipCall;
-}
-
-static bool deleteMemObjInfo(layer_data *my_data, void *object, VkDeviceMemory mem) {
-    bool skipCall = false;
-    auto item = my_data->memObjMap.find(mem);
-    if (item != my_data->memObjMap.end()) {
-        my_data->memObjMap.erase(item);
-    } else {
-        skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                           (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MEM_OBJ, "MEM",
-                           "Request to delete memory object 0x%" PRIxLEAST64 " not present in memory Object Map", (uint64_t)mem);
-    }
-    return skipCall;
+    return skip_call;
 }
 
 static bool freeMemObjInfo(layer_data *dev_data, void *object, VkDeviceMemory mem, bool internal) {
-    bool skipCall = false;
+    bool skip_call = false;
     // Parse global list to find info w/ mem
-    DEVICE_MEM_INFO *pInfo = get_mem_obj_info(dev_data, mem);
+    DEVICE_MEM_INFO *pInfo = getMemObjInfo(dev_data, mem);
     if (pInfo) {
-        if (pInfo->allocInfo.allocationSize == 0 && !internal) {
-            // TODO: Verify against Valid Use section
-            skipCall = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                               (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MEM_OBJ, "MEM",
-                               "Attempting to free memory associated with a Persistent Image, 0x%" PRIxLEAST64 ", "
-                               "this should not be explicitly freed\n",
-                               (uint64_t)mem);
-        } else {
-            // Clear any CB bindings for completed CBs
-            //   TODO : Is there a better place to do this?
+        // TODO: Verify against Valid Use section
+        // Clear any CB bindings for completed CBs
+        //   TODO : Is there a better place to do this?
 
-            assert(pInfo->object != VK_NULL_HANDLE);
-            // clear_cmd_buf_and_mem_references removes elements from
-            // pInfo->commandBufferBindings -- this copy not needed in c++14,
-            // and probably not needed in practice in c++11
-            auto bindings = pInfo->commandBufferBindings;
-            for (auto cb : bindings) {
-                if (!dev_data->globalInFlightCmdBuffers.count(cb)) {
-                    clear_cmd_buf_and_mem_references(dev_data, cb);
-                }
+        assert(pInfo->object != VK_NULL_HANDLE);
+        // clear_cmd_buf_and_mem_references removes elements from
+        // pInfo->command_buffer_bindings -- this copy not needed in c++14,
+        // and probably not needed in practice in c++11
+        auto bindings = pInfo->command_buffer_bindings;
+        for (auto cb : bindings) {
+            if (!dev_data->globalInFlightCmdBuffers.count(cb)) {
+                clear_cmd_buf_and_mem_references(dev_data, cb);
             }
-
-            // Now verify that no references to this mem obj remain and remove bindings
-            if (pInfo->commandBufferBindings.size() || pInfo->objBindings.size()) {
-                skipCall |= reportMemReferencesAndCleanUp(dev_data, pInfo);
-            }
-            // Delete mem obj info
-            skipCall |= deleteMemObjInfo(dev_data, object, mem);
         }
+
+        // Now verify that no references to this mem obj remain and remove bindings
+        if (pInfo->command_buffer_bindings.size() || pInfo->obj_bindings.size()) {
+            skip_call |= reportMemReferencesAndCleanUp(dev_data, pInfo);
+        }
+        // Delete mem obj info
+        dev_data->memObjMap.erase(dev_data->memObjMap.find(mem));
+    } else if (VK_NULL_HANDLE != mem) {
+        // The request is to free an invalid, non-zero handle
+        skip_call = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                            VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            reinterpret_cast<uint64_t &>(mem), __LINE__,
+                            MEMTRACK_INVALID_MEM_OBJ,
+                            "MEM", "Request to delete memory object 0x%"
+                            PRIxLEAST64 " not present in memory Object Map",
+                            reinterpret_cast<uint64_t &>(mem));
     }
-    return skipCall;
+    return skip_call;
 }
 
 static const char *object_type_to_string(VkDebugReportObjectTypeEXT type) {
@@ -536,6 +650,16 @@
         return "buffer";
     case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT:
         return "swapchain";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT:
+        return "descriptor set";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT:
+        return "buffer";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT:
+        return "event";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT:
+        return "query pool";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT:
+        return "pipeline";
     default:
         return "unknown";
     }
@@ -547,17 +671,17 @@
 // TODO : This only applied to Buffer, Image, and Swapchain objects now, how should it be updated/customized?
 static bool clear_object_binding(layer_data *dev_data, uint64_t handle, VkDebugReportObjectTypeEXT type) {
     // TODO : Need to customize images/buffers/swapchains to track mem binding and clear it here appropriately
-    bool skipCall = false;
+    bool skip_call = false;
     VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type);
     if (pMemBinding) {
-        DEVICE_MEM_INFO *pMemObjInfo = get_mem_obj_info(dev_data, *pMemBinding);
+        DEVICE_MEM_INFO *pMemObjInfo = getMemObjInfo(dev_data, *pMemBinding);
         // TODO : Make sure this is a reasonable way to reset mem binding
         *pMemBinding = VK_NULL_HANDLE;
         if (pMemObjInfo) {
             // This obj is bound to a memory object. Remove the reference to this object in that memory object's list,
             // and set the objects memory binding pointer to NULL.
-            if (!pMemObjInfo->objBindings.erase({handle, type})) {
-                skipCall |=
+            if (!pMemObjInfo->obj_bindings.erase({handle, type})) {
+                skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_OBJECT,
                             "MEM", "While trying to clear mem binding for %s obj 0x%" PRIxLEAST64
                                    ", unable to find that object referenced by mem obj 0x%" PRIxLEAST64,
@@ -565,7 +689,35 @@
             }
         }
     }
-    return skipCall;
+    return skip_call;
+}
+
+// Check to see if memory was ever bound to this image
+bool ValidateMemoryIsBoundToImage(const layer_data *dev_data, const IMAGE_NODE *image_node, const char *api_name) {
+    bool result = false;
+    if (0 == (static_cast<uint32_t>(image_node->createInfo.flags) & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
+        if (0 == image_node->mem) {
+            result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                             reinterpret_cast<const uint64_t &>(image_node->image), __LINE__, MEMTRACK_OBJECT_NOT_BOUND, "MEM",
+                             "%s: VkImage object 0x%" PRIxLEAST64 " used without first calling vkBindImageMemory.", api_name,
+                             reinterpret_cast<const uint64_t &>(image_node->image));
+        }
+    }
+    return result;
+}
+
+// Check to see if memory was bound to this buffer
+bool ValidateMemoryIsBoundToBuffer(const layer_data *dev_data, const BUFFER_NODE *buffer_node, const char *api_name) {
+    bool result = false;
+    if (0 == (static_cast<uint32_t>(buffer_node->createInfo.flags) & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) {
+        if (0 == buffer_node->mem) {
+            result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
+                             reinterpret_cast<const uint64_t &>(buffer_node->buffer), __LINE__, MEMTRACK_OBJECT_NOT_BOUND, "MEM",
+                             "%s: VkBuffer object 0x%" PRIxLEAST64 " used without first calling vkBindBufferMemory.", api_name,
+                             reinterpret_cast<const uint64_t &>(buffer_node->buffer));
+        }
+    }
+    return result;
 }
 
 // For NULL mem case, output warning
@@ -575,32 +727,32 @@
 //  Add reference off of objInfo
 static bool set_mem_binding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle,
                                 VkDebugReportObjectTypeEXT type, const char *apiName) {
-    bool skipCall = false;
+    bool skip_call = false;
     // Handle NULL case separately, just clear previous binding & decrement reference
     if (mem == VK_NULL_HANDLE) {
         // TODO: Verify against Valid Use section of spec.
-        skipCall = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_MEM_OBJ,
-                           "MEM", "In %s, attempting to Bind Obj(0x%" PRIxLEAST64 ") to NULL", apiName, handle);
+        skip_call = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_MEM_OBJ,
+                            "MEM", "In %s, attempting to Bind Obj(0x%" PRIxLEAST64 ") to NULL", apiName, handle);
     } else {
         VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type);
         assert(pMemBinding);
-        DEVICE_MEM_INFO *pMemInfo = get_mem_obj_info(dev_data, mem);
+        DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, mem);
         if (pMemInfo) {
-            DEVICE_MEM_INFO *pPrevBinding = get_mem_obj_info(dev_data, *pMemBinding);
+            DEVICE_MEM_INFO *pPrevBinding = getMemObjInfo(dev_data, *pMemBinding);
             if (pPrevBinding != NULL) {
-                skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, __LINE__, MEMTRACK_REBIND_OBJECT,
-                                    "MEM", "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64
-                                           ") which has already been bound to mem object 0x%" PRIxLEAST64,
-                                    apiName, (uint64_t)mem, handle, (uint64_t)pPrevBinding->mem);
+                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                     VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, __LINE__, MEMTRACK_REBIND_OBJECT,
+                                     "MEM", "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64
+                                            ") which has already been bound to mem object 0x%" PRIxLEAST64,
+                                     apiName, (uint64_t)mem, handle, (uint64_t)pPrevBinding->mem);
             } else {
-                pMemInfo->objBindings.insert({handle, type});
+                pMemInfo->obj_bindings.insert({handle, type});
                 // For image objects, make sure default memory state is correctly set
                 // TODO : What's the best/correct way to handle this?
                 if (VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT == type) {
-                    auto const image_node = dev_data->imageMap.find(VkImage(handle));
-                    if (image_node != dev_data->imageMap.end()) {
-                        VkImageCreateInfo ici = image_node->second.createInfo;
+                    auto const image_node = getImageNode(dev_data, VkImage(handle));
+                    if (image_node) {
+                        VkImageCreateInfo ici = image_node->createInfo;
                         if (ici.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
                             // TODO::  More memory state transition stuff.
                         }
@@ -610,7 +762,7 @@
             }
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 // For NULL mem case, clear any previous binding Else...
@@ -621,43 +773,48 @@
 // Return VK_TRUE if addition is successful, VK_FALSE otherwise
 static bool set_sparse_mem_binding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle,
                                        VkDebugReportObjectTypeEXT type, const char *apiName) {
-    bool skipCall = VK_FALSE;
+    bool skip_call = VK_FALSE;
     // Handle NULL case separately, just clear previous binding & decrement reference
     if (mem == VK_NULL_HANDLE) {
-        skipCall = clear_object_binding(dev_data, handle, type);
+        skip_call = clear_object_binding(dev_data, handle, type);
     } else {
         VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type);
         assert(pMemBinding);
-        DEVICE_MEM_INFO *pInfo = get_mem_obj_info(dev_data, mem);
+        DEVICE_MEM_INFO *pInfo = getMemObjInfo(dev_data, mem);
         if (pInfo) {
-            pInfo->objBindings.insert({handle, type});
+            pInfo->obj_bindings.insert({handle, type});
             // Need to set mem binding for this object
             *pMemBinding = mem;
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
-// For given Object, get 'mem' obj that it's bound to or NULL if no binding
-static bool get_mem_binding_from_object(layer_data *dev_data, const uint64_t handle,
-                                            const VkDebugReportObjectTypeEXT type, VkDeviceMemory *mem) {
-    bool skipCall = false;
+// For handle of given object type, return memory binding
+static bool get_mem_for_type(layer_data *dev_data, uint64_t handle, VkDebugReportObjectTypeEXT type, VkDeviceMemory *mem) {
+    bool skip_call = false;
     *mem = VK_NULL_HANDLE;
-    VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type);
-    if (pMemBinding) {
-        *mem = *pMemBinding;
-    } else {
-        skipCall = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_OBJECT,
-                           "MEM", "Trying to get mem binding for object 0x%" PRIxLEAST64 " but no such object in %s list", handle,
-                           object_type_to_string(type));
+    switch (type) {
+    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
+        *mem = getImageNode(dev_data, VkImage(handle))->mem;
+        break;
+    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
+        *mem = getBufferNode(dev_data, VkBuffer(handle))->mem;
+        break;
+    default:
+        assert(0);
     }
-    return skipCall;
+    if (!*mem) {
+        skip_call = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_OBJECT,
+                            "MEM", "Trying to get mem binding for %s object 0x%" PRIxLEAST64
+                                   " but binding is NULL. Has memory been bound to this object?",
+                            object_type_to_string(type), handle);
+    }
+    return skip_call;
 }
 
 // Print details of MemObjInfo list
 static void print_mem_list(layer_data *dev_data) {
-    DEVICE_MEM_INFO *pInfo = NULL;
-
     // Early out if info is not requested
     if (!(dev_data->report_data->active_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)) {
         return;
@@ -674,17 +831,17 @@
         return;
 
     for (auto ii = dev_data->memObjMap.begin(); ii != dev_data->memObjMap.end(); ++ii) {
-        pInfo = &(*ii).second;
+        auto mem_info = (*ii).second.get();
 
         log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
-                __LINE__, MEMTRACK_NONE, "MEM", "    ===MemObjInfo at 0x%p===", (void *)pInfo);
+                __LINE__, MEMTRACK_NONE, "MEM", "    ===MemObjInfo at 0x%p===", (void *)mem_info);
         log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
-                __LINE__, MEMTRACK_NONE, "MEM", "    Mem object: 0x%" PRIxLEAST64, (uint64_t)(pInfo->mem));
+                __LINE__, MEMTRACK_NONE, "MEM", "    Mem object: 0x%" PRIxLEAST64, (uint64_t)(mem_info->mem));
         log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
                 __LINE__, MEMTRACK_NONE, "MEM", "    Ref Count: " PRINTF_SIZE_T_SPECIFIER,
-                pInfo->commandBufferBindings.size() + pInfo->objBindings.size());
-        if (0 != pInfo->allocInfo.allocationSize) {
-            string pAllocInfoMsg = vk_print_vkmemoryallocateinfo(&pInfo->allocInfo, "MEM(INFO):         ");
+                mem_info->command_buffer_bindings.size() + mem_info->obj_bindings.size());
+        if (0 != mem_info->alloc_info.allocationSize) {
+            string pAllocInfoMsg = vk_print_vkmemoryallocateinfo(&mem_info->alloc_info, "MEM(INFO):         ");
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
                     __LINE__, MEMTRACK_NONE, "MEM", "    Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
         } else {
@@ -694,9 +851,9 @@
 
         log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
                 __LINE__, MEMTRACK_NONE, "MEM", "    VK OBJECT Binding list of size " PRINTF_SIZE_T_SPECIFIER " elements:",
-                pInfo->objBindings.size());
-        if (pInfo->objBindings.size() > 0) {
-            for (auto obj : pInfo->objBindings) {
+                mem_info->obj_bindings.size());
+        if (mem_info->obj_bindings.size() > 0) {
+            for (auto obj : mem_info->obj_bindings) {
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                         0, __LINE__, MEMTRACK_NONE, "MEM", "       VK OBJECT 0x%" PRIx64, obj.handle);
             }
@@ -705,9 +862,9 @@
         log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
                 __LINE__, MEMTRACK_NONE, "MEM",
                 "    VK Command Buffer (CB) binding list of size " PRINTF_SIZE_T_SPECIFIER " elements",
-                pInfo->commandBufferBindings.size());
-        if (pInfo->commandBufferBindings.size() > 0) {
-            for (auto cb : pInfo->commandBufferBindings) {
+                mem_info->command_buffer_bindings.size());
+        if (mem_info->command_buffer_bindings.size() > 0) {
+            for (auto cb : mem_info->command_buffer_bindings) {
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                         0, __LINE__, MEMTRACK_NONE, "MEM", "      VK CB 0x%p", cb);
             }
@@ -1377,7 +1534,7 @@
 
 static void collect_interface_by_descriptor_slot(debug_report_data *report_data, shader_module const *src,
                                                  std::unordered_set<uint32_t> const &accessible_ids,
-                                                 std::map<descriptor_slot_t, interface_var> &out) {
+                                                 std::vector<std::pair<descriptor_slot_t, interface_var>> &out) {
 
     std::unordered_map<unsigned, unsigned> var_sets;
     std::unordered_map<unsigned, unsigned> var_bindings;
@@ -1406,23 +1563,13 @@
             unsigned set = value_or_default(var_sets, insn.word(2), 0);
             unsigned binding = value_or_default(var_bindings, insn.word(2), 0);
 
-            auto existing_it = out.find(std::make_pair(set, binding));
-            if (existing_it != out.end()) {
-                /* conflict within spv image */
-                log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
-                        __LINE__, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC",
-                        "var %d (type %d) in %s interface in descriptor slot (%u,%u) conflicts with existing definition",
-                        insn.word(2), insn.word(1), storage_class_name(insn.word(3)), existing_it->first.first,
-                        existing_it->first.second);
-            }
-
             interface_var v;
             v.id = insn.word(2);
             v.type_id = insn.word(1);
             v.offset = 0;
             v.is_patch = false;
             v.is_block_member = false;
-            out[std::make_pair(set, binding)] = v;
+            out.emplace_back(std::make_pair(set, binding), v);
         }
     }
 }
@@ -1633,6 +1780,7 @@
 
     auto it_a = attribs.begin();
     auto it_b = inputs.begin();
+    bool used = false;
 
     while ((attribs.size() > 0 && it_a != attribs.end()) || (inputs.size() > 0 && it_b != inputs.end())) {
         bool a_at_end = attribs.size() == 0 || it_a == attribs.end();
@@ -1640,11 +1788,12 @@
         auto a_first = a_at_end ? 0 : it_a->first;
         auto b_first = b_at_end ? 0 : it_b->first.first;
         if (!a_at_end && (b_at_end || a_first < b_first)) {
-            if (log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+            if (!used && log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                         __LINE__, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC",
                         "Vertex attribute at location %d not consumed by VS", a_first)) {
                 pass = false;
             }
+            used = false;
             it_a++;
         } else if (!b_at_end && (a_at_end || b_first < a_first)) {
             if (log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0,
@@ -1669,7 +1818,7 @@
             }
 
             /* OK! */
-            it_a++;
+            used = true;
             it_b++;
         }
     }
@@ -1678,12 +1827,17 @@
 }
 
 static bool validate_fs_outputs_against_render_pass(debug_report_data *report_data, shader_module const *fs,
-                                                    spirv_inst_iter entrypoint, RENDER_PASS_NODE const *rp, uint32_t subpass) {
+                                                    spirv_inst_iter entrypoint, VkRenderPassCreateInfo const *rpci,
+                                                    uint32_t subpass_index) {
     std::map<location_t, interface_var> outputs;
     std::map<uint32_t, VkFormat> color_attachments;
-    for (auto i = 0u; i < rp->subpassColorFormats[subpass].size(); i++) {
-        if (rp->subpassColorFormats[subpass][i] != VK_FORMAT_UNDEFINED) {
-            color_attachments[i] = rp->subpassColorFormats[subpass][i];
+    auto subpass = rpci->pSubpasses[subpass_index];
+    for (auto i = 0u; i < subpass.colorAttachmentCount; ++i) {
+        uint32_t attachment = subpass.pColorAttachments[i].attachment;
+        if (attachment == VK_ATTACHMENT_UNUSED)
+            continue;
+        if (rpci->pAttachments[attachment].format != VK_FORMAT_UNDEFINED) {
+            color_attachments[i] = rpci->pAttachments[attachment].format;
         }
     }
 
@@ -1857,7 +2011,7 @@
 }
 
 static bool validate_push_constant_block_against_pipeline(debug_report_data *report_data,
-                                                          std::vector<VkPushConstantRange> const *pushConstantRanges,
+                                                          std::vector<VkPushConstantRange> const *push_constant_ranges,
                                                           shader_module const *src, spirv_inst_iter type,
                                                           VkShaderStageFlagBits stage) {
     bool pass = true;
@@ -1877,7 +2031,7 @@
                 auto size = 4; /* bytes; TODO: calculate this based on the type */
 
                 bool found_range = false;
-                for (auto const &range : *pushConstantRanges) {
+                for (auto const &range : *push_constant_ranges) {
                     if (range.offset <= offset && range.offset + range.size >= offset + size) {
                         found_range = true;
 
@@ -1912,15 +2066,15 @@
 }
 
 static bool validate_push_constant_usage(debug_report_data *report_data,
-                                         std::vector<VkPushConstantRange> const *pushConstantRanges, shader_module const *src,
+                                         std::vector<VkPushConstantRange> const *push_constant_ranges, shader_module const *src,
                                          std::unordered_set<uint32_t> accessible_ids, VkShaderStageFlagBits stage) {
     bool pass = true;
 
     for (auto id : accessible_ids) {
         auto def_insn = src->get_def(id);
         if (def_insn.opcode() == spv::OpVariable && def_insn.word(3) == spv::StorageClassPushConstant) {
-            pass &= validate_push_constant_block_against_pipeline(report_data, pushConstantRanges, src,
-                                                                 src->get_def(def_insn.word(1)), stage);
+            pass &= validate_push_constant_block_against_pipeline(report_data, push_constant_ranges, src,
+                                                                  src->get_def(def_insn.word(1)), stage);
         }
     }
 
@@ -1934,10 +2088,10 @@
     if (!pipelineLayout)
         return nullptr;
 
-    if (slot.first >= pipelineLayout->descriptorSetLayouts.size())
+    if (slot.first >= pipelineLayout->set_layouts.size())
         return nullptr;
 
-    return pipelineLayout->setLayouts[slot.first]->GetDescriptorSetLayoutBindingPtrFromBinding(slot.second);
+    return pipelineLayout->set_layouts[slot.first]->GetDescriptorSetLayoutBindingPtrFromBinding(slot.second);
 }
 
 // Block of code at start here for managing/tracking Pipeline state that this layer cares about
@@ -1985,15 +2139,15 @@
     return it->second;
 }
 
-static FRAMEBUFFER_NODE *getFramebuffer(layer_data *my_data, VkFramebuffer framebuffer) {
+static FRAMEBUFFER_NODE *getFramebuffer(const layer_data *my_data, VkFramebuffer framebuffer) {
     auto it = my_data->frameBufferMap.find(framebuffer);
     if (it == my_data->frameBufferMap.end()) {
         return nullptr;
     }
-    return &it->second;
+    return it->second.get();
 }
 
-static cvdescriptorset::DescriptorSetLayout const *getDescriptorSetLayout(layer_data const *my_data, VkDescriptorSetLayout dsLayout) {
+cvdescriptorset::DescriptorSetLayout const *getDescriptorSetLayout(layer_data const *my_data, VkDescriptorSetLayout dsLayout) {
     auto it = my_data->descriptorSetLayoutMap.find(dsLayout);
     if (it == my_data->descriptorSetLayoutMap.end()) {
         return nullptr;
@@ -2066,20 +2220,34 @@
 
 // Verify attachment reference compatibility according to spec
 //  If one array is larger, treat missing elements of shorter array as VK_ATTACHMENT_UNUSED & other array much match this
-//  If both AttachmentReference arrays have requested index, check their corresponding AttachementDescriptions
+//  If both AttachmentReference arrays have requested index, check their corresponding AttachmentDescriptions
 //   to make sure that format and samples counts match.
 //  If not, they are not compatible.
 static bool attachment_references_compatible(const uint32_t index, const VkAttachmentReference *pPrimary,
                                              const uint32_t primaryCount, const VkAttachmentDescription *pPrimaryAttachments,
                                              const VkAttachmentReference *pSecondary, const uint32_t secondaryCount,
                                              const VkAttachmentDescription *pSecondaryAttachments) {
+    // Check potential NULL cases first to avoid nullptr issues later
+    if (pPrimary == nullptr) {
+        if (pSecondary == nullptr) {
+            return true;
+        }
+        return false;
+    } else if (pSecondary == nullptr) {
+        return false;
+    }
     if (index >= primaryCount) { // Check secondary as if primary is VK_ATTACHMENT_UNUSED
         if (VK_ATTACHMENT_UNUSED == pSecondary[index].attachment)
             return true;
     } else if (index >= secondaryCount) { // Check primary as if secondary is VK_ATTACHMENT_UNUSED
         if (VK_ATTACHMENT_UNUSED == pPrimary[index].attachment)
             return true;
-    } else { // format and sample count must match
+    } else { // Format and sample count must match
+        if ((pPrimary[index].attachment == VK_ATTACHMENT_UNUSED) && (pSecondary[index].attachment == VK_ATTACHMENT_UNUSED)) {
+            return true;
+        } else if ((pPrimary[index].attachment == VK_ATTACHMENT_UNUSED) || (pSecondary[index].attachment == VK_ATTACHMENT_UNUSED)) {
+            return false;
+        }
         if ((pPrimaryAttachments[pPrimary[index].attachment].format ==
              pSecondaryAttachments[pSecondary[index].attachment].format) &&
             (pPrimaryAttachments[pPrimary[index].attachment].samples ==
@@ -2089,32 +2257,10 @@
     // Format and sample counts didn't match
     return false;
 }
-
-// For give primary and secondary RenderPass objects, verify that they're compatible
-static bool verify_renderpass_compatibility(layer_data *my_data, const VkRenderPass primaryRP, const VkRenderPass secondaryRP,
-                                            string &errorMsg) {
-    auto primary_render_pass = getRenderPass(my_data, primaryRP);
-    auto secondary_render_pass = getRenderPass(my_data, secondaryRP);
-
-    if (!primary_render_pass) {
-        stringstream errorStr;
-        errorStr << "invalid VkRenderPass (" << primaryRP << ")";
-        errorMsg = errorStr.str();
-        return false;
-    }
-
-    if (!secondary_render_pass) {
-        stringstream errorStr;
-        errorStr << "invalid VkRenderPass (" << secondaryRP << ")";
-        errorMsg = errorStr.str();
-        return false;
-    }
-    // Trivial pass case is exact same RP
-    if (primaryRP == secondaryRP) {
-        return true;
-    }
-    const VkRenderPassCreateInfo *primaryRPCI = primary_render_pass->pCreateInfo;
-    const VkRenderPassCreateInfo *secondaryRPCI = secondary_render_pass->pCreateInfo;
+// TODO : Scrub verify_renderpass_compatibility() and validateRenderPassCompatibility() and unify them and/or share code
+// For given primary RenderPass object and secondry RenderPassCreateInfo, verify that they're compatible
+static bool verify_renderpass_compatibility(const layer_data *my_data, const VkRenderPassCreateInfo *primaryRPCI,
+                                            const VkRenderPassCreateInfo *secondaryRPCI, string &errorMsg) {
     if (primaryRPCI->subpassCount != secondaryRPCI->subpassCount) {
         stringstream errorStr;
         errorStr << "RenderPass for primary cmdBuffer has " << primaryRPCI->subpassCount
@@ -2177,23 +2323,18 @@
 // For given cvdescriptorset::DescriptorSet, verify that its Set is compatible w/ the setLayout corresponding to
 // pipelineLayout[layoutIndex]
 static bool verify_set_layout_compatibility(layer_data *my_data, const cvdescriptorset::DescriptorSet *pSet,
-                                            const VkPipelineLayout layout, const uint32_t layoutIndex, string &errorMsg) {
-    auto pipeline_layout = getPipelineLayout(my_data, layout);
-    if (!pipeline_layout) {
+                                            PIPELINE_LAYOUT_NODE const *pipeline_layout, const uint32_t layoutIndex,
+                                            string &errorMsg) {
+    auto num_sets = pipeline_layout->set_layouts.size();
+    if (layoutIndex >= num_sets) {
         stringstream errorStr;
-        errorStr << "invalid VkPipelineLayout (" << layout << ")";
+        errorStr << "VkPipelineLayout (" << pipeline_layout->layout << ") only contains " << num_sets
+                 << " setLayouts corresponding to sets 0-" << num_sets - 1 << ", but you're attempting to bind set to index "
+                 << layoutIndex;
         errorMsg = errorStr.str();
         return false;
     }
-    if (layoutIndex >= pipeline_layout->descriptorSetLayouts.size()) {
-        stringstream errorStr;
-        errorStr << "VkPipelineLayout (" << layout << ") only contains " << pipeline_layout->descriptorSetLayouts.size()
-                 << " setLayouts corresponding to sets 0-" << pipeline_layout->descriptorSetLayouts.size() - 1
-                 << ", but you're attempting to bind set to index " << layoutIndex;
-        errorMsg = errorStr.str();
-        return false;
-    }
-    auto layout_node = pipeline_layout->setLayouts[layoutIndex];
+    auto layout_node = pipeline_layout->set_layouts[layoutIndex];
     return pSet->IsCompatible(layout_node, &errorMsg);
 }
 
@@ -2260,7 +2401,8 @@
     }
 
     case spv::OpTypeSampler:
-        return descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLER;
+        return descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLER ||
+            descriptor_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
 
     case spv::OpTypeSampledImage:
         if (descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
@@ -2293,7 +2435,8 @@
                 return descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
             }
         } else if (sampled == 1) {
-            return descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+            return descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
+                descriptor_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
         } else {
             return descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
         }
@@ -2460,6 +2603,45 @@
     return pass;
 }
 
+
+static uint32_t descriptor_type_to_reqs(shader_module const *module, uint32_t type_id) {
+    auto type = module->get_def(type_id);
+
+    while (true) {
+        switch (type.opcode()) {
+        case spv::OpTypeArray:
+        case spv::OpTypeSampledImage:
+            type = module->get_def(type.word(2));
+            break;
+        case spv::OpTypePointer:
+            type = module->get_def(type.word(3));
+            break;
+        case spv::OpTypeImage: {
+            auto dim = type.word(3);
+            auto arrayed = type.word(5);
+            auto msaa = type.word(6);
+
+            switch (dim) {
+            case spv::Dim1D:
+                return arrayed ? DESCRIPTOR_REQ_VIEW_TYPE_1D_ARRAY : DESCRIPTOR_REQ_VIEW_TYPE_1D;
+            case spv::Dim2D:
+                return (msaa ? DESCRIPTOR_REQ_MULTI_SAMPLE : DESCRIPTOR_REQ_SINGLE_SAMPLE) |
+                    (arrayed ? DESCRIPTOR_REQ_VIEW_TYPE_2D_ARRAY : DESCRIPTOR_REQ_VIEW_TYPE_2D);
+            case spv::Dim3D:
+                return DESCRIPTOR_REQ_VIEW_TYPE_3D;
+            case spv::DimCube:
+                return arrayed ? DESCRIPTOR_REQ_VIEW_TYPE_CUBE_ARRAY : DESCRIPTOR_REQ_VIEW_TYPE_CUBE;
+            default:  // subpass, buffer, etc.
+                return 0;
+            }
+        }
+        default:
+            return 0;
+        }
+    }
+}
+
+
 static bool validate_pipeline_shader_stage(debug_report_data *report_data,
                                            VkPipelineShaderStageCreateInfo const *pStage,
                                            PIPELINE_NODE *pipeline,
@@ -2492,22 +2674,22 @@
     mark_accessible_ids(module, entrypoint, accessible_ids);
 
     /* validate descriptor set layout against what the entrypoint actually uses */
-    std::map<descriptor_slot_t, interface_var> descriptor_uses;
+    std::vector<std::pair<descriptor_slot_t, interface_var>> descriptor_uses;
     collect_interface_by_descriptor_slot(report_data, module, accessible_ids, descriptor_uses);
 
-    auto pipelineLayout = pipeline->pipelineLayout;
+    auto pipelineLayout = pipeline->pipeline_layout;
 
     /* validate push constant usage */
-    pass &= validate_push_constant_usage(report_data, &pipelineLayout->pushConstantRanges,
-                                        module, accessible_ids, pStage->stage);
+    pass &= validate_push_constant_usage(report_data, &pipelineLayout.push_constant_ranges, module, accessible_ids, pStage->stage);
 
     /* validate descriptor use */
     for (auto use : descriptor_uses) {
         // While validating shaders capture which slots are used by the pipeline
-        pipeline->active_slots[use.first.first].insert(use.first.second);
+        auto & reqs = pipeline->active_slots[use.first.first][use.first.second];
+        reqs = descriptor_req(reqs | descriptor_type_to_reqs(module, use.second.type_id));
 
         /* verify given pipelineLayout has requested setLayout with requested binding */
-        const auto & binding = get_descriptor_binding(pipelineLayout, use.first);
+        const auto &binding = get_descriptor_binding(&pipelineLayout, use.first);
         unsigned required_descriptor_count;
 
         if (!binding) {
@@ -2605,9 +2787,9 @@
         }
     }
 
-    if (shaders[fragment_stage] && pPipeline->renderPass) {
+    if (shaders[fragment_stage]) {
         pass &= validate_fs_outputs_against_render_pass(report_data, shaders[fragment_stage], entrypoints[fragment_stage],
-                                                        pPipeline->renderPass, pCreateInfo->subpass);
+                                                        pPipeline->render_pass_ci.ptr(), pCreateInfo->subpass);
     }
 
     return pass;
@@ -2623,13 +2805,13 @@
     return validate_pipeline_shader_stage(report_data, &pCreateInfo->stage, pPipeline,
                                           &module, &entrypoint, enabledFeatures, shaderModuleMap);
 }
-
 // Return Set node ptr for specified set or else NULL
-static cvdescriptorset::DescriptorSet *getSetNode(layer_data *my_data, const VkDescriptorSet set) {
-    if (my_data->setMap.find(set) == my_data->setMap.end()) {
+cvdescriptorset::DescriptorSet *getSetNode(const layer_data *my_data, VkDescriptorSet set) {
+    auto set_it = my_data->setMap.find(set);
+    if (set_it == my_data->setMap.end()) {
         return NULL;
     }
-    return my_data->setMap[set];
+    return set_it->second;
 }
 // For the given command buffer, verify and update the state for activeSetBindingsPairs
 //  This includes:
@@ -2640,7 +2822,7 @@
 //  3. Grow updateBuffers for pCB to include buffers from STORAGE*_BUFFER descriptor buffers
 static bool validate_and_update_drawtime_descriptor_state(
     layer_data *dev_data, GLOBAL_CB_NODE *pCB,
-    const vector<std::tuple<cvdescriptorset::DescriptorSet *, unordered_set<uint32_t>,
+    const vector<std::tuple<cvdescriptorset::DescriptorSet *, unordered_map<uint32_t, descriptor_req>,
                             std::vector<uint32_t> const *>> &activeSetBindingsPairs) {
     bool result = false;
     for (auto set_bindings_pair : activeSetBindingsPairs) {
@@ -2659,17 +2841,6 @@
     }
     return result;
 }
-// TODO : This is a temp function that naively updates bound storage images and buffers based on which descriptor sets are bound.
-//   When validate_and_update_draw_state() handles compute shaders so that active_slots is correct for compute pipelines, this
-//   function can be killed and validate_and_update_draw_state() used instead
-static void update_shader_storage_images_and_buffers(layer_data *dev_data, GLOBAL_CB_NODE *pCB) {
-    // For the bound descriptor sets, pull off any storage images and buffers
-    //  This may be more than are actually updated depending on which are active, but for now this is a stop-gap for compute
-    //  pipelines
-    for (auto set : pCB->lastBound[VK_PIPELINE_BIND_POINT_COMPUTE].uniqueBoundSets) {
-        set->GetAllStorageUpdates(&pCB->updateBuffers, &pCB->updateImages);
-    }
-}
 
 // For given pipeline, return number of MSAA samples, or one if MSAA disabled
 static VkSampleCountFlagBits getNumSamples(PIPELINE_NODE const *pipe) {
@@ -2680,26 +2851,100 @@
     return VK_SAMPLE_COUNT_1_BIT;
 }
 
-// Validate draw-time state related to the PSO
-static bool validatePipelineDrawtimeState(layer_data const *my_data, const GLOBAL_CB_NODE *pCB,
-                                          const VkPipelineBindPoint pipelineBindPoint, PIPELINE_NODE const *pPipeline) {
-    bool skip_call = false;
-    if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
-        // Verify that any MSAA request in PSO matches sample# in bound FB
-        // Skip the check if rasterization is disabled.
-        if (!pPipeline->graphicsPipelineCI.pRasterizationState ||
-            (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
-            VkSampleCountFlagBits pso_num_samples = getNumSamples(pPipeline);
-            if (pCB->activeRenderPass) {
-                const VkRenderPassCreateInfo *render_pass_info = pCB->activeRenderPass->pCreateInfo;
-                const VkSubpassDescription *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
-                VkSampleCountFlagBits subpass_num_samples = VkSampleCountFlagBits(0);
-                uint32_t i;
+static void list_bits(std::ostream& s, uint32_t bits) {
+    for (int i = 0; i < 32 && bits; i++) {
+        if (bits & (1 << i)) {
+            s << i;
+            bits &= ~(1 << i);
+            if (bits) {
+                s << ",";
+            }
+        }
+    }
+}
 
-                const VkPipelineColorBlendStateCreateInfo *color_blend_state = pPipeline->graphicsPipelineCI.pColorBlendState;
-                if ((color_blend_state != NULL) && (pCB->activeSubpass == pPipeline->graphicsPipelineCI.subpass) &&
-                    (color_blend_state->attachmentCount != subpass_desc->colorAttachmentCount)) {
-                    skip_call |=
+// Validate draw-time state related to the PSO
+static bool validatePipelineDrawtimeState(layer_data const *my_data,
+                                          LAST_BOUND_STATE const &state,
+                                          const GLOBAL_CB_NODE *pCB,
+                                          PIPELINE_NODE const *pPipeline) {
+    bool skip_call = false;
+
+    // Verify Vtx binding
+    if (pPipeline->vertexBindingDescriptions.size() > 0) {
+        for (size_t i = 0; i < pPipeline->vertexBindingDescriptions.size(); i++) {
+            auto vertex_binding = pPipeline->vertexBindingDescriptions[i].binding;
+            if ((pCB->currentDrawData.buffers.size() < (vertex_binding + 1)) ||
+                (pCB->currentDrawData.buffers[vertex_binding] == VK_NULL_HANDLE)) {
+                skip_call |= log_msg(
+                    my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                    DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
+                    "The Pipeline State Object (0x%" PRIxLEAST64 ") expects that this Command Buffer's vertex binding Index %u "
+                    "should be set via vkCmdBindVertexBuffers. This is because VkVertexInputBindingDescription struct "
+                    "at index " PRINTF_SIZE_T_SPECIFIER " of pVertexBindingDescriptions has a binding value of %u.",
+                    (uint64_t)state.pipeline, vertex_binding, i, vertex_binding);
+            }
+        }
+    } else {
+        if (!pCB->currentDrawData.buffers.empty()) {
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0,
+                              0, __LINE__, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
+                              "Vertex buffers are bound to command buffer (0x%" PRIxLEAST64
+                              ") but no vertex buffers are attached to this Pipeline State Object (0x%" PRIxLEAST64 ").",
+                              (uint64_t)pCB->commandBuffer, (uint64_t)state.pipeline);
+        }
+    }
+    // If Viewport or scissors are dynamic, verify that dynamic count matches PSO count.
+    // Skip check if rasterization is disabled or there is no viewport.
+    if ((!pPipeline->graphicsPipelineCI.pRasterizationState ||
+         (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) &&
+        pPipeline->graphicsPipelineCI.pViewportState) {
+        bool dynViewport = isDynamic(pPipeline, VK_DYNAMIC_STATE_VIEWPORT);
+        bool dynScissor = isDynamic(pPipeline, VK_DYNAMIC_STATE_SCISSOR);
+
+        if (dynViewport) {
+            auto requiredViewportsMask = (1 << pPipeline->graphicsPipelineCI.pViewportState->viewportCount) - 1;
+            auto missingViewportMask = ~pCB->viewportMask & requiredViewportsMask;
+            if (missingViewportMask) {
+                std::stringstream ss;
+                ss << "Dynamic viewport(s) ";
+                list_bits(ss, missingViewportMask);
+                ss << " are used by PSO, but were not provided via calls to vkCmdSetViewport().";
+                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+                                     __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
+                                     "%s", ss.str().c_str());
+            }
+        }
+
+        if (dynScissor) {
+            auto requiredScissorMask = (1 << pPipeline->graphicsPipelineCI.pViewportState->scissorCount) - 1;
+            auto missingScissorMask = ~pCB->scissorMask & requiredScissorMask;
+            if (missingScissorMask) {
+                std::stringstream ss;
+                ss << "Dynamic scissor(s) ";
+                list_bits(ss, missingScissorMask);
+                ss << " are used by PSO, but were not provided via calls to vkCmdSetScissor().";
+                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+                                     __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
+                                     "%s", ss.str().c_str());
+            }
+        }
+    }
+
+    // Verify that any MSAA request in PSO matches sample# in bound FB
+    // Skip the check if rasterization is disabled.
+    if (!pPipeline->graphicsPipelineCI.pRasterizationState ||
+        (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
+        VkSampleCountFlagBits pso_num_samples = getNumSamples(pPipeline);
+        if (pCB->activeRenderPass) {
+            const VkRenderPassCreateInfo *render_pass_info = pCB->activeRenderPass->pCreateInfo;
+            const VkSubpassDescription *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
+            uint32_t i;
+
+            const safe_VkPipelineColorBlendStateCreateInfo *color_blend_state = pPipeline->graphicsPipelineCI.pColorBlendState;
+            if ((color_blend_state != NULL) && (pCB->activeSubpass == pPipeline->graphicsPipelineCI.subpass) &&
+                (color_blend_state->attachmentCount != subpass_desc->colorAttachmentCount)) {
+                skip_call |=
                         log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
                                 reinterpret_cast<const uint64_t &>(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
                                 "Render pass subpass %u mismatch with blending state defined and blend state attachment "
@@ -2707,53 +2952,56 @@
                                 "must be the same at draw-time.",
                                 pCB->activeSubpass, color_blend_state->attachmentCount, subpass_desc->colorAttachmentCount,
                                 reinterpret_cast<const uint64_t &>(pPipeline->pipeline));
-                }
+            }
 
-                for (i = 0; i < subpass_desc->colorAttachmentCount; i++) {
-                    VkSampleCountFlagBits samples;
+            unsigned subpass_num_samples = 0;
 
-                    if (subpass_desc->pColorAttachments[i].attachment == VK_ATTACHMENT_UNUSED)
-                        continue;
+            for (i = 0; i < subpass_desc->colorAttachmentCount; i++) {
+                auto attachment = subpass_desc->pColorAttachments[i].attachment;
+                if (attachment != VK_ATTACHMENT_UNUSED)
+                    subpass_num_samples |= (unsigned)render_pass_info->pAttachments[attachment].samples;
+            }
 
-                    samples = render_pass_info->pAttachments[subpass_desc->pColorAttachments[i].attachment].samples;
-                    if (subpass_num_samples == static_cast<VkSampleCountFlagBits>(0)) {
-                        subpass_num_samples = samples;
-                    } else if (subpass_num_samples != samples) {
-                        subpass_num_samples = static_cast<VkSampleCountFlagBits>(-1);
-                        break;
-                    }
-                }
-                if ((subpass_desc->pDepthStencilAttachment != NULL) &&
-                    (subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
-                    const VkSampleCountFlagBits samples =
-                        render_pass_info->pAttachments[subpass_desc->pDepthStencilAttachment->attachment].samples;
-                    if (subpass_num_samples == static_cast<VkSampleCountFlagBits>(0))
-                        subpass_num_samples = samples;
-                    else if (subpass_num_samples != samples)
-                        subpass_num_samples = static_cast<VkSampleCountFlagBits>(-1);
-                }
+            if (subpass_desc->pDepthStencilAttachment &&
+                subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
+                auto attachment = subpass_desc->pDepthStencilAttachment->attachment;
+                subpass_num_samples |= (unsigned)render_pass_info->pAttachments[attachment].samples;
+            }
 
-                if (((subpass_desc->colorAttachmentCount > 0) || (subpass_desc->pDepthStencilAttachment != NULL)) &&
-                    (pso_num_samples != subpass_num_samples)) {
-                    skip_call |=
+            if (subpass_num_samples && static_cast<unsigned>(pso_num_samples) != subpass_num_samples) {
+                skip_call |=
                         log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
                                 reinterpret_cast<const uint64_t &>(pPipeline->pipeline), __LINE__, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS",
                                 "Num samples mismatch! At draw-time in Pipeline (0x%" PRIxLEAST64
                                 ") with %u samples while current RenderPass (0x%" PRIxLEAST64 ") w/ %u samples!",
                                 reinterpret_cast<const uint64_t &>(pPipeline->pipeline), pso_num_samples,
                                 reinterpret_cast<const uint64_t &>(pCB->activeRenderPass->renderPass), subpass_num_samples);
-                }
-            } else {
-                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
-                                     reinterpret_cast<const uint64_t &>(pPipeline->pipeline), __LINE__, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS",
-                                     "No active render pass found at draw-time in Pipeline (0x%" PRIxLEAST64 ")!",
-                                     reinterpret_cast<const uint64_t &>(pPipeline->pipeline));
             }
+        } else {
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+                                 reinterpret_cast<const uint64_t &>(pPipeline->pipeline), __LINE__, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS",
+                                 "No active render pass found at draw-time in Pipeline (0x%" PRIxLEAST64 ")!",
+                                 reinterpret_cast<const uint64_t &>(pPipeline->pipeline));
         }
-        // TODO : Add more checks here
-    } else {
-        // TODO : Validate non-gfx pipeline updates
     }
+    // Verify that PSO creation renderPass is compatible with active renderPass
+    if (pCB->activeRenderPass) {
+        std::string err_string;
+        if ((pCB->activeRenderPass->renderPass != pPipeline->graphicsPipelineCI.renderPass) &&
+            !verify_renderpass_compatibility(my_data, pCB->activeRenderPass->pCreateInfo, pPipeline->render_pass_ci.ptr(),
+                                             err_string)) {
+            // renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with
+            skip_call |=
+                log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+                        reinterpret_cast<const uint64_t &>(pPipeline->pipeline), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
+                        "At Draw time the active render pass (0x%" PRIxLEAST64 ") is incompatible w/ gfx pipeline "
+                        "(0x%" PRIxLEAST64 ") that was created w/ render pass (0x%" PRIxLEAST64 ") due to: %s",
+                        reinterpret_cast<uint64_t &>(pCB->activeRenderPass->renderPass), reinterpret_cast<uint64_t &>(pPipeline),
+                        reinterpret_cast<const uint64_t &>(pPipeline->graphicsPipelineCI.renderPass), err_string.c_str());
+        }
+    }
+    // TODO : Add more checks here
+
     return skip_call;
 }
 
@@ -2775,20 +3023,14 @@
     // First check flag states
     if (VK_PIPELINE_BIND_POINT_GRAPHICS == bindPoint)
         result = validate_draw_state_flags(my_data, pCB, pPipe, indexedDraw);
-    else {
-        // First block of code below to validate active sets should eventually
-        //  work for the compute case but currently doesn't so return early for now
-        // TODO : When active sets in compute shaders are correctly parsed,
-        //  stop returning early here and handle them in top block below
-        return result;
-    }
 
     // Now complete other state checks
-    // TODO : When Compute shaders are properly parsed, fix this section to validate them as well
-    if (state.pipelineLayout) {
+    if (VK_NULL_HANDLE != state.pipeline_layout.layout) {
         string errorString;
+        auto pipeline_layout = pPipe->pipeline_layout;
+
         // Need a vector (vs. std::set) of active Sets for dynamicOffset validation in case same set bound w/ different offsets
-        vector<std::tuple<cvdescriptorset::DescriptorSet *, unordered_set<uint32_t>, std::vector<uint32_t> const *>> activeSetBindingsPairs;
+        vector<std::tuple<cvdescriptorset::DescriptorSet *, unordered_map<uint32_t, descriptor_req>, std::vector<uint32_t> const *>> activeSetBindingsPairs;
         for (auto & setBindingPair : pPipe->active_slots) {
             uint32_t setIndex = setBindingPair.first;
             // If valid set is not bound throw an error
@@ -2797,16 +3039,17 @@
                                   DRAWSTATE_DESCRIPTOR_SET_NOT_BOUND, "DS",
                                   "VkPipeline 0x%" PRIxLEAST64 " uses set #%u but that set is not bound.", (uint64_t)pPipe->pipeline,
                                   setIndex);
-            } else if (!verify_set_layout_compatibility(my_data, state.boundDescriptorSets[setIndex],
-                                                        pPipe->graphicsPipelineCI.layout, setIndex, errorString)) {
-                // Set is bound but not compatible w/ overlapping pipelineLayout from PSO
+            } else if (!verify_set_layout_compatibility(my_data, state.boundDescriptorSets[setIndex], &pipeline_layout, setIndex,
+                                                        errorString)) {
+                // Set is bound but not compatible w/ overlapping pipeline_layout from PSO
                 VkDescriptorSet setHandle = state.boundDescriptorSets[setIndex]->GetSet();
                 result |=
                     log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                             (uint64_t)setHandle, __LINE__, DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, "DS",
                             "VkDescriptorSet (0x%" PRIxLEAST64
                             ") bound as set #%u is not compatible with overlapping VkPipelineLayout 0x%" PRIxLEAST64 " due to: %s",
-                            (uint64_t)setHandle, setIndex, (uint64_t)pPipe->graphicsPipelineCI.layout, errorString.c_str());
+                            reinterpret_cast<uint64_t &>(setHandle), setIndex, reinterpret_cast<uint64_t &>(pipeline_layout.layout),
+                            errorString.c_str());
             } else { // Valid set is bound and layout compatible, validate that it's updated
                 // Pull the set node
                 cvdescriptorset::DescriptorSet *pSet = state.boundDescriptorSets[setIndex];
@@ -2817,7 +3060,7 @@
                 //  If it has immutable samplers, we'll flag error later as needed depending on binding
                 if (!pSet->IsUpdated()) {
                     for (auto binding : setBindingPair.second) {
-                        if (!pSet->GetImmutableSamplerPtrFromBinding(binding)) {
+                        if (!pSet->GetImmutableSamplerPtrFromBinding(binding.first)) {
                             result |= log_msg(
                                 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                                 (uint64_t)pSet->GetSet(), __LINE__, DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
@@ -2832,59 +3075,10 @@
         // For given active slots, verify any dynamic descriptors and record updated images & buffers
         result |= validate_and_update_drawtime_descriptor_state(my_data, pCB, activeSetBindingsPairs);
     }
-    // TODO : If/when compute pipelines/shaders are handled above, code below is only for gfx bind poing
-    //if (VK_PIPELINE_BIND_POINT_GRAPHICS == bindPoint) {
-    // Verify Vtx binding
-    if (pPipe->vertexBindingDescriptions.size() > 0) {
-        for (size_t i = 0; i < pPipe->vertexBindingDescriptions.size(); i++) {
-            if ((pCB->currentDrawData.buffers.size() < (i + 1)) || (pCB->currentDrawData.buffers[i] == VK_NULL_HANDLE)) {
-                result |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                  __LINE__, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
-                                  "The Pipeline State Object (0x%" PRIxLEAST64
-                                  ") expects that this Command Buffer's vertex binding Index " PRINTF_SIZE_T_SPECIFIER
-                                  " should be set via vkCmdBindVertexBuffers.",
-                                  (uint64_t)state.pipeline, i);
-            }
-        }
-    } else {
-        if (!pCB->currentDrawData.buffers.empty()) {
-            result |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0,
-                              0, __LINE__, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
-                              "Vertex buffers are bound to command buffer (0x%" PRIxLEAST64
-                              ") but no vertex buffers are attached to this Pipeline State Object (0x%" PRIxLEAST64 ").",
-                              (uint64_t)pCB->commandBuffer, (uint64_t)state.pipeline);
-        }
-    }
-    // If Viewport or scissors are dynamic, verify that dynamic count matches PSO count.
-    // Skip check if rasterization is disabled or there is no viewport.
-    if ((!pPipe->graphicsPipelineCI.pRasterizationState ||
-         (pPipe->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) &&
-        pPipe->graphicsPipelineCI.pViewportState) {
-        bool dynViewport = isDynamic(pPipe, VK_DYNAMIC_STATE_VIEWPORT);
-        bool dynScissor = isDynamic(pPipe, VK_DYNAMIC_STATE_SCISSOR);
-        if (dynViewport) {
-            if (pCB->viewports.size() != pPipe->graphicsPipelineCI.pViewportState->viewportCount) {
-                result |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                  __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
-                                  "Dynamic viewportCount from vkCmdSetViewport() is " PRINTF_SIZE_T_SPECIFIER
-                                  ", but PSO viewportCount is %u. These counts must match.",
-                                  pCB->viewports.size(), pPipe->graphicsPipelineCI.pViewportState->viewportCount);
-            }
-        }
-        if (dynScissor) {
-            if (pCB->scissors.size() != pPipe->graphicsPipelineCI.pViewportState->scissorCount) {
-                result |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                  __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
-                                  "Dynamic scissorCount from vkCmdSetScissor() is " PRINTF_SIZE_T_SPECIFIER
-                                  ", but PSO scissorCount is %u. These counts must match.",
-                                  pCB->scissors.size(), pPipe->graphicsPipelineCI.pViewportState->scissorCount);
-            }
-        }
-    }
-    //} // end of "if (VK_PIPELINE_BIND_POINT_GRAPHICS == bindPoint) {" block
 
     // Check general pipeline state that needs to be validated at drawtime
-    result |= validatePipelineDrawtimeState(my_data, pCB, bindPoint, pPipe);
+    if (VK_PIPELINE_BIND_POINT_GRAPHICS == bindPoint)
+        result |= validatePipelineDrawtimeState(my_data, state, pCB, pPipe);
 
     return result;
 }
@@ -2917,7 +3111,7 @@
 // Verify that create state for a pipeline is valid
 static bool verifyPipelineCreateState(layer_data *my_data, const VkDevice device, std::vector<PIPELINE_NODE *> pPipelines,
                                       int pipelineIndex) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     PIPELINE_NODE *pPipeline = pPipelines[pipelineIndex];
 
@@ -2928,12 +3122,12 @@
         PIPELINE_NODE *pBasePipeline = nullptr;
         if (!((pPipeline->graphicsPipelineCI.basePipelineHandle != VK_NULL_HANDLE) ^
               (pPipeline->graphicsPipelineCI.basePipelineIndex != -1))) {
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
-                                "Invalid Pipeline CreateInfo: exactly one of base pipeline index and handle must be specified");
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
+                                 "Invalid Pipeline CreateInfo: exactly one of base pipeline index and handle must be specified");
         } else if (pPipeline->graphicsPipelineCI.basePipelineIndex != -1) {
             if (pPipeline->graphicsPipelineCI.basePipelineIndex >= pipelineIndex) {
-                skipCall |=
+                skip_call |=
                     log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                             DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
                             "Invalid Pipeline CreateInfo: base pipeline must occur earlier in array than derivative pipeline.");
@@ -2945,9 +3139,9 @@
         }
 
         if (pBasePipeline && !(pBasePipeline->graphicsPipelineCI.flags & VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT)) {
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
-                                "Invalid Pipeline CreateInfo: base pipeline does not allow derivatives.");
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
+                                 "Invalid Pipeline CreateInfo: base pipeline does not allow derivatives.");
         }
     }
 
@@ -2956,25 +3150,23 @@
             if (pPipeline->attachments.size() > 1) {
                 VkPipelineColorBlendAttachmentState *pAttachments = &pPipeline->attachments[0];
                 for (size_t i = 1; i < pPipeline->attachments.size(); i++) {
-                    if ((pAttachments[0].blendEnable != pAttachments[i].blendEnable) ||
-                        (pAttachments[0].srcColorBlendFactor != pAttachments[i].srcColorBlendFactor) ||
-                        (pAttachments[0].dstColorBlendFactor != pAttachments[i].dstColorBlendFactor) ||
-                        (pAttachments[0].colorBlendOp != pAttachments[i].colorBlendOp) ||
-                        (pAttachments[0].srcAlphaBlendFactor != pAttachments[i].srcAlphaBlendFactor) ||
-                        (pAttachments[0].dstAlphaBlendFactor != pAttachments[i].dstAlphaBlendFactor) ||
-                        (pAttachments[0].alphaBlendOp != pAttachments[i].alphaBlendOp) ||
-                        (pAttachments[0].colorWriteMask != pAttachments[i].colorWriteMask)) {
-                        skipCall |=
-                            log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_INDEPENDENT_BLEND, "DS", "Invalid Pipeline CreateInfo: If independent blend feature not "
-                            "enabled, all elements of pAttachments must be identical");
+                    // Quoting the spec: "If [the independent blend] feature is not enabled, the VkPipelineColorBlendAttachmentState
+                    // settings for all color attachments must be identical." VkPipelineColorBlendAttachmentState contains
+                    // only attachment state, so memcmp is best suited for the comparison
+                    if (memcmp(static_cast<const void *>(pAttachments), static_cast<const void *>(&pAttachments[i]),
+                               sizeof(pAttachments[0]))) {
+                        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                             __LINE__, DRAWSTATE_INDEPENDENT_BLEND, "DS",
+                                             "Invalid Pipeline CreateInfo: If independent blend feature not "
+                                             "enabled, all elements of pAttachments must be identical");
+                        break;
                     }
                 }
             }
         }
         if (!my_data->phys_dev_properties.features.logicOp &&
             (pPipeline->graphicsPipelineCI.pColorBlendState->logicOpEnable != VK_FALSE)) {
-            skipCall |=
+            skip_call |=
                 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_DISABLED_LOGIC_OP, "DS",
                         "Invalid Pipeline CreateInfo: If logic operations feature not enabled, logicOpEnable must be VK_FALSE");
@@ -2982,7 +3174,7 @@
         if ((pPipeline->graphicsPipelineCI.pColorBlendState->logicOpEnable == VK_TRUE) &&
             ((pPipeline->graphicsPipelineCI.pColorBlendState->logicOp < VK_LOGIC_OP_CLEAR) ||
              (pPipeline->graphicsPipelineCI.pColorBlendState->logicOp > VK_LOGIC_OP_SET))) {
-            skipCall |=
+            skip_call |=
                 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_INVALID_LOGIC_OP, "DS",
                         "Invalid Pipeline CreateInfo: If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value");
@@ -2995,88 +3187,89 @@
     auto renderPass = getRenderPass(my_data, pPipeline->graphicsPipelineCI.renderPass);
     if (renderPass &&
         pPipeline->graphicsPipelineCI.subpass >= renderPass->pCreateInfo->subpassCount) {
-        skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: Subpass index %u "
-                                                                           "is out of range for this renderpass (0..%u)",
-                            pPipeline->graphicsPipelineCI.subpass, renderPass->pCreateInfo->subpassCount - 1);
+        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                             DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: Subpass index %u "
+                                                                            "is out of range for this renderpass (0..%u)",
+                             pPipeline->graphicsPipelineCI.subpass, renderPass->pCreateInfo->subpassCount - 1);
     }
 
     if (!validate_and_capture_pipeline_shader_state(my_data->report_data, pPipeline, &my_data->phys_dev_properties.features,
                                                     my_data->shaderModuleMap)) {
-        skipCall = true;
+        skip_call = true;
     }
     // Each shader's stage must be unique
     if (pPipeline->duplicate_shaders) {
         for (uint32_t stage = VK_SHADER_STAGE_VERTEX_BIT; stage & VK_SHADER_STAGE_ALL_GRAPHICS; stage <<= 1) {
             if (pPipeline->duplicate_shaders & stage) {
-                skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
-                                    __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
-                                    "Invalid Pipeline CreateInfo State: Multiple shaders provided for stage %s",
-                                    string_VkShaderStageFlagBits(VkShaderStageFlagBits(stage)));
+                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+                                     __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
+                                     "Invalid Pipeline CreateInfo State: Multiple shaders provided for stage %s",
+                                     string_VkShaderStageFlagBits(VkShaderStageFlagBits(stage)));
             }
         }
     }
     // VS is required
     if (!(pPipeline->active_shaders & VK_SHADER_STAGE_VERTEX_BIT)) {
-        skipCall |=
+        skip_call |=
             log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                     DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: Vtx Shader required");
     }
     // Either both or neither TC/TE shaders should be defined
     if (((pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) == 0) !=
         ((pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) == 0)) {
-        skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
-                            "Invalid Pipeline CreateInfo State: TE and TC shaders must be included or excluded as a pair");
+        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                             DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
+                             "Invalid Pipeline CreateInfo State: TE and TC shaders must be included or excluded as a pair");
     }
     // Compute shaders should be specified independent of Gfx shaders
     if ((pPipeline->active_shaders & VK_SHADER_STAGE_COMPUTE_BIT) &&
         (pPipeline->active_shaders &
          (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT |
           VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT))) {
-        skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
-                            "Invalid Pipeline CreateInfo State: Do not specify Compute Shader for Gfx Pipeline");
+        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                             DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
+                             "Invalid Pipeline CreateInfo State: Do not specify Compute Shader for Gfx Pipeline");
     }
     // VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive topology is only valid for tessellation pipelines.
     // Mismatching primitive topology and tessellation fails graphics pipeline creation.
     if (pPipeline->active_shaders & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) &&
         (!pPipeline->graphicsPipelineCI.pInputAssemblyState ||
          pPipeline->graphicsPipelineCI.pInputAssemblyState->topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST)) {
-        skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
-                                                                           "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST must be set as IA "
-                                                                           "topology for tessellation pipelines");
+        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                             DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
+                                                                            "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST must be set as IA "
+                                                                            "topology for tessellation pipelines");
     }
     if (pPipeline->graphicsPipelineCI.pInputAssemblyState &&
         pPipeline->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) {
         if (~pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
-                                                                               "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
-                                                                               "topology is only valid for tessellation pipelines");
+            skip_call |=
+                log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                        DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
+                                                                       "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
+                                                                       "topology is only valid for tessellation pipelines");
         }
         if (!pPipeline->graphicsPipelineCI.pTessellationState) {
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
-                                "Invalid Pipeline CreateInfo State: "
-                                "pTessellationState is NULL when VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
-                                "topology used. pTessellationState must not be NULL in this case.");
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
+                                 "Invalid Pipeline CreateInfo State: "
+                                 "pTessellationState is NULL when VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
+                                 "topology used. pTessellationState must not be NULL in this case.");
         } else if (!pPipeline->graphicsPipelineCI.pTessellationState->patchControlPoints ||
                    (pPipeline->graphicsPipelineCI.pTessellationState->patchControlPoints > 32)) {
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
-                                                                               "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
-                                                                               "topology used with patchControlPoints value %u."
-                                                                               " patchControlPoints should be >0 and <=32.",
-                                pPipeline->graphicsPipelineCI.pTessellationState->patchControlPoints);
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: "
+                                                                                "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive "
+                                                                                "topology used with patchControlPoints value %u."
+                                                                                " patchControlPoints should be >0 and <=32.",
+                                 pPipeline->graphicsPipelineCI.pTessellationState->patchControlPoints);
         }
     }
     // If a rasterization state is provided, make sure that the line width conforms to the HW.
     if (pPipeline->graphicsPipelineCI.pRasterizationState) {
         if (!isDynamic(pPipeline, VK_DYNAMIC_STATE_LINE_WIDTH)) {
-            skipCall |= verifyLineWidth(my_data, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, reinterpret_cast<uint64_t &>(pPipeline),
-                                        pPipeline->graphicsPipelineCI.pRasterizationState->lineWidth);
+            skip_call |= verifyLineWidth(my_data, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, reinterpret_cast<uint64_t &>(pPipeline),
+                                         pPipeline->graphicsPipelineCI.pRasterizationState->lineWidth);
         }
     }
     // Viewport state must be included if rasterization is enabled.
@@ -3085,17 +3278,17 @@
     if (!pPipeline->graphicsPipelineCI.pRasterizationState ||
         (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
         if (!pPipeline->graphicsPipelineCI.pViewportState) {
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", "Gfx Pipeline pViewportState is null. Even if viewport "
-                                                                           "and scissors are dynamic PSO must include "
-                                                                           "viewportCount and scissorCount in pViewportState.");
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", "Gfx Pipeline pViewportState is null. Even if viewport "
+                                                                            "and scissors are dynamic PSO must include "
+                                                                            "viewportCount and scissorCount in pViewportState.");
         } else if (pPipeline->graphicsPipelineCI.pViewportState->scissorCount !=
                    pPipeline->graphicsPipelineCI.pViewportState->viewportCount) {
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
-                                "Gfx Pipeline viewport count (%u) must match scissor count (%u).",
-                                pPipeline->graphicsPipelineCI.pViewportState->viewportCount,
-                                pPipeline->graphicsPipelineCI.pViewportState->scissorCount);
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
+                                 "Gfx Pipeline viewport count (%u) must match scissor count (%u).",
+                                 pPipeline->graphicsPipelineCI.pViewportState->viewportCount,
+                                 pPipeline->graphicsPipelineCI.pViewportState->scissorCount);
         } else {
             // If viewport or scissor are not dynamic, then verify that data is appropriate for count
             bool dynViewport = isDynamic(pPipeline, VK_DYNAMIC_STATE_VIEWPORT);
@@ -3103,28 +3296,29 @@
             if (!dynViewport) {
                 if (pPipeline->graphicsPipelineCI.pViewportState->viewportCount &&
                     !pPipeline->graphicsPipelineCI.pViewportState->pViewports) {
-                    skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                        __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
-                                        "Gfx Pipeline viewportCount is %u, but pViewports is NULL. For non-zero viewportCount, you "
-                                        "must either include pViewports data, or include viewport in pDynamicState and set it with "
-                                        "vkCmdSetViewport().",
-                                        pPipeline->graphicsPipelineCI.pViewportState->viewportCount);
+                    skip_call |=
+                        log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
+                                "Gfx Pipeline viewportCount is %u, but pViewports is NULL. For non-zero viewportCount, you "
+                                "must either include pViewports data, or include viewport in pDynamicState and set it with "
+                                "vkCmdSetViewport().",
+                                pPipeline->graphicsPipelineCI.pViewportState->viewportCount);
                 }
             }
             if (!dynScissor) {
                 if (pPipeline->graphicsPipelineCI.pViewportState->scissorCount &&
                     !pPipeline->graphicsPipelineCI.pViewportState->pScissors) {
-                    skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                        __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
-                                        "Gfx Pipeline scissorCount is %u, but pScissors is NULL. For non-zero scissorCount, you "
-                                        "must either include pScissors data, or include scissor in pDynamicState and set it with "
-                                        "vkCmdSetScissor().",
-                                        pPipeline->graphicsPipelineCI.pViewportState->scissorCount);
+                    skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                         __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
+                                         "Gfx Pipeline scissorCount is %u, but pScissors is NULL. For non-zero scissorCount, you "
+                                         "must either include pScissors data, or include scissor in pDynamicState and set it with "
+                                         "vkCmdSetScissor().",
+                                         pPipeline->graphicsPipelineCI.pViewportState->scissorCount);
                 }
             }
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 // Free the Pipeline nodes
@@ -3140,11 +3334,12 @@
 // Block of code at start here specifically for managing/tracking DSs
 
 // Return Pool node ptr for specified pool or else NULL
-static DESCRIPTOR_POOL_NODE *getPoolNode(layer_data *my_data, const VkDescriptorPool pool) {
-    if (my_data->descriptorPoolMap.find(pool) == my_data->descriptorPoolMap.end()) {
+DESCRIPTOR_POOL_NODE *getPoolNode(const layer_data *dev_data, const VkDescriptorPool pool) {
+    auto pool_it = dev_data->descriptorPoolMap.find(pool);
+    if (pool_it == dev_data->descriptorPoolMap.end()) {
         return NULL;
     }
-    return my_data->descriptorPoolMap[pool];
+    return pool_it->second;
 }
 
 // Return false if update struct is of valid type, otherwise flag error and return code from callback
@@ -3189,7 +3384,7 @@
 static bool validateUpdateConsistency(layer_data *my_data, const VkDevice device, const VkDescriptorType layout_type,
                                       const GENERIC_HEADER *pUpdateStruct, uint32_t startIndex, uint32_t endIndex) {
     // First get actual type of update
-    bool skipCall = false;
+    bool skip_call = false;
     VkDescriptorType actualType = VK_DESCRIPTOR_TYPE_MAX_ENUM;
     switch (pUpdateStruct->sType) {
     case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
@@ -3200,21 +3395,21 @@
         return false;
         break;
     default:
-        skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
-                            "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree",
-                            string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
+        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                             DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
+                             "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree",
+                             string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
     }
-    if (!skipCall) {
+    if (!skip_call) {
         if (layout_type != actualType) {
-            skipCall |= log_msg(
+            skip_call |= log_msg(
                 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                 DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS",
                 "Write descriptor update has descriptor type %s that does not match overlapping binding descriptor type of %s!",
                 string_VkDescriptorType(actualType), string_VkDescriptorType(layout_type));
         }
     }
-    return skipCall;
+    return skip_call;
 }
 //TODO: Consolidate functions
 bool FindLayout(const GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, IMAGE_CMD_BUF_LAYOUT_NODE &node, const VkImageAspectFlags aspectMask) {
@@ -3308,13 +3503,13 @@
     auto sub_data = my_data->imageSubresourceMap.find(image);
     if (sub_data == my_data->imageSubresourceMap.end())
         return false;
-    auto imgIt = my_data->imageMap.find(image);
-    if (imgIt == my_data->imageMap.end())
+    auto img_node = getImageNode(my_data, image);
+    if (!img_node)
         return false;
     bool ignoreGlobal = false;
     // TODO: Make this robust for >1 aspect mask. Now it will just say ignore
     // potential errors in this case.
-    if (sub_data->second.size() >= (imgIt->second.createInfo.arrayLayers * imgIt->second.createInfo.mipLevels + 1)) {
+    if (sub_data->second.size() >= (img_node->createInfo.arrayLayers * img_node->createInfo.mipLevels + 1)) {
         ignoreGlobal = true;
     }
     for (auto imgsubpair : sub_data->second) {
@@ -3390,16 +3585,24 @@
 }
 
 void SetLayout(const layer_data *dev_data, GLOBAL_CB_NODE *pCB, VkImageView imageView, const VkImageLayout &layout) {
-    auto image_view_data = dev_data->imageViewMap.find(imageView);
-    assert(image_view_data != dev_data->imageViewMap.end());
-    const VkImage &image = image_view_data->second.image;
-    const VkImageSubresourceRange &subRange = image_view_data->second.subresourceRange;
+    auto iv_data = getImageViewData(dev_data, imageView);
+    assert(iv_data);
+    const VkImage &image = iv_data->image;
+    const VkImageSubresourceRange &subRange = iv_data->subresourceRange;
     // TODO: Do not iterate over every possibility - consolidate where possible
     for (uint32_t j = 0; j < subRange.levelCount; j++) {
         uint32_t level = subRange.baseMipLevel + j;
         for (uint32_t k = 0; k < subRange.layerCount; k++) {
             uint32_t layer = subRange.baseArrayLayer + k;
             VkImageSubresource sub = {subRange.aspectMask, level, layer};
+            // TODO: If ImageView was created with depth or stencil, transition both layouts as
+            // the aspectMask is ignored and both are used. Verify that the extra implicit layout
+            // is OK for descriptor set layout validation
+            if (subRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
+                if (vk_format_is_depth_and_stencil(iv_data->format)) {
+                    sub.aspectMask |= (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
+                }
+            }
             SetLayout(pCB, image, sub, layout);
         }
     }
@@ -3428,7 +3631,7 @@
     return skip_call;
 }
 
-// Free the descriptor set, remove it from setMap and invalidate any cmd buffers that it was bound to
+// Remove set from setMap and delete the set
 static void freeDescriptorSet(layer_data *dev_data, cvdescriptorset::DescriptorSet *descriptor_set) {
     dev_data->setMap.erase(descriptor_set->GetSet());
     delete descriptor_set;
@@ -3451,23 +3654,17 @@
 static void clearDescriptorPool(layer_data *my_data, const VkDevice device, const VkDescriptorPool pool,
                                 VkDescriptorPoolResetFlags flags) {
     DESCRIPTOR_POOL_NODE *pPool = getPoolNode(my_data, pool);
-    if (!pPool) {
-        log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-                (uint64_t)pool, __LINE__, DRAWSTATE_INVALID_POOL, "DS",
-                "Unable to find pool node for pool 0x%" PRIxLEAST64 " specified in vkResetDescriptorPool() call", (uint64_t)pool);
-    } else {
-        // TODO: validate flags
-        // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
-        for (auto ds : pPool->sets) {
-            freeDescriptorSet(my_data, ds);
-        }
-        pPool->sets.clear();
-        // Reset available count for each type and available sets for this pool
-        for (uint32_t i = 0; i < pPool->availableDescriptorTypeCount.size(); ++i) {
-            pPool->availableDescriptorTypeCount[i] = pPool->maxDescriptorTypeCount[i];
-        }
-        pPool->availableSets = pPool->maxSets;
+    // TODO: validate flags
+    // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
+    for (auto ds : pPool->sets) {
+        freeDescriptorSet(my_data, ds);
     }
+    pPool->sets.clear();
+    // Reset available count for each type and available sets for this pool
+    for (uint32_t i = 0; i < pPool->availableDescriptorTypeCount.size(); ++i) {
+        pPool->availableDescriptorTypeCount[i] = pPool->maxDescriptorTypeCount[i];
+    }
+    pPool->availableSets = pPool->maxSets;
 }
 
 // For given CB object, fetch associated CB Node from map
@@ -3542,11 +3739,11 @@
 
 // Add specified CMD to the CmdBuffer in given pCB, flagging errors if CB is not
 //  in the recording state or if there's an issue with the Cmd ordering
-static bool addCmd(const layer_data *my_data, GLOBAL_CB_NODE *pCB, const CMD_TYPE cmd, const char *caller_name) {
-    bool skipCall = false;
-    auto pool_data = my_data->commandPoolMap.find(pCB->createInfo.commandPool);
-    if (pool_data != my_data->commandPoolMap.end()) {
-        VkQueueFlags flags = my_data->phys_dev_properties.queue_family_properties[pool_data->second.queueFamilyIndex].queueFlags;
+static bool addCmd(layer_data *my_data, GLOBAL_CB_NODE *pCB, const CMD_TYPE cmd, const char *caller_name) {
+    bool skip_call = false;
+    auto pPool = getCommandPoolNode(my_data, pCB->createInfo.commandPool);
+    if (pPool) {
+        VkQueueFlags flags = my_data->phys_dev_properties.queue_family_properties[pPool->queueFamilyIndex].queueFlags;
         switch (cmd) {
         case CMD_BINDPIPELINE:
         case CMD_BINDPIPELINEDELTA:
@@ -3561,7 +3758,7 @@
         case CMD_RESETQUERYPOOL:
         case CMD_COPYQUERYPOOLRESULTS:
         case CMD_WRITETIMESTAMP:
-            skipCall |= checkGraphicsOrComputeBit(my_data, flags, cmdTypeToString(cmd).c_str());
+            skip_call |= checkGraphicsOrComputeBit(my_data, flags, cmdTypeToString(cmd).c_str());
             break;
         case CMD_SETVIEWPORTSTATE:
         case CMD_SETSCISSORSTATE:
@@ -3585,11 +3782,11 @@
         case CMD_BEGINRENDERPASS:
         case CMD_NEXTSUBPASS:
         case CMD_ENDRENDERPASS:
-            skipCall |= checkGraphicsBit(my_data, flags, cmdTypeToString(cmd).c_str());
+            skip_call |= checkGraphicsBit(my_data, flags, cmdTypeToString(cmd).c_str());
             break;
         case CMD_DISPATCH:
         case CMD_DISPATCHINDIRECT:
-            skipCall |= checkComputeBit(my_data, flags, cmdTypeToString(cmd).c_str());
+            skip_call |= checkComputeBit(my_data, flags, cmdTypeToString(cmd).c_str());
             break;
         case CMD_COPYBUFFER:
         case CMD_COPYIMAGE:
@@ -3606,16 +3803,60 @@
         }
     }
     if (pCB->state != CB_RECORDING) {
-        skipCall |= report_error_no_cb_begin(my_data, pCB->commandBuffer, caller_name);
+        skip_call |= report_error_no_cb_begin(my_data, pCB->commandBuffer, caller_name);
     } else {
-        skipCall |= validateCmdsInCmdBuffer(my_data, pCB, cmd);
+        skip_call |= validateCmdsInCmdBuffer(my_data, pCB, cmd);
         CMD_NODE cmdNode = {};
         // init cmd node and append to end of cmd LL
         cmdNode.cmdNumber = ++pCB->numCmds;
         cmdNode.type = cmd;
         pCB->cmds.push_back(cmdNode);
     }
-    return skipCall;
+    return skip_call;
+}
+// Tie the VK_OBJECT to the cmd buffer which includes:
+//  Add object_binding to cmd buffer
+//  Add cb_binding to object
+static void addCommandBufferBinding(std::unordered_set<GLOBAL_CB_NODE *> *cb_bindings, VK_OBJECT obj, GLOBAL_CB_NODE *cb_node) {
+    cb_bindings->insert(cb_node);
+    cb_node->object_bindings.insert(obj);
+}
+// For a given object, if cb_node is in that objects cb_bindings, remove cb_node
+static void removeCommandBufferBinding(layer_data *dev_data, VK_OBJECT const *object, GLOBAL_CB_NODE *cb_node) {
+    switch (object->type) {
+    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
+        auto img_node = getImageNode(dev_data, reinterpret_cast<const VkImage &>(object->handle));
+        if (img_node)
+            img_node->cb_bindings.erase(cb_node);
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
+        auto buf_node = getBufferNode(dev_data, reinterpret_cast<const VkBuffer &>(object->handle));
+        if (buf_node)
+            buf_node->cb_bindings.erase(cb_node);
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: {
+        auto evt_node = getEventNode(dev_data, reinterpret_cast<const VkEvent &>(object->handle));
+        if (evt_node)
+            evt_node->cb_bindings.erase(cb_node);
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: {
+        auto qp_node = getQueryPoolNode(dev_data, reinterpret_cast<const VkQueryPool &>(object->handle));
+        if (qp_node)
+            qp_node->cb_bindings.erase(cb_node);
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: {
+        auto pipe_node = getPipeline(dev_data, reinterpret_cast<const VkPipeline &>(object->handle));
+        if (pipe_node)
+            pipe_node->cb_bindings.erase(cb_node);
+        break;
+    }
+    default:
+        assert(0); // unhandled object type
+    }
 }
 // Reset the command buffer state
 //  Maintain the createInfo and set state to CB_NEW, but clear all other state
@@ -3633,8 +3874,8 @@
         pCB->state = CB_NEW;
         pCB->submitCount = 0;
         pCB->status = 0;
-        pCB->viewports.clear();
-        pCB->scissors.clear();
+        pCB->viewportMask = 0;
+        pCB->scissorMask = 0;
 
         for (uint32_t i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; ++i) {
             // Before clearing lastBoundState, remove any CB bindings from all uniqueBoundSets
@@ -3648,14 +3889,10 @@
         pCB->activeRenderPass = nullptr;
         pCB->activeSubpassContents = VK_SUBPASS_CONTENTS_INLINE;
         pCB->activeSubpass = 0;
-        pCB->lastSubmittedFence = VK_NULL_HANDLE;
-        pCB->lastSubmittedQueue = VK_NULL_HANDLE;
-        pCB->destroyedSets.clear();
-        pCB->updatedSets.clear();
-        pCB->destroyedFramebuffers.clear();
+        pCB->broken_bindings.clear();
         pCB->waitedEvents.clear();
-        pCB->semaphores.clear();
         pCB->events.clear();
+        pCB->writeEventsBeforeWait.clear();
         pCB->waitedEventsBeforeQueryReset.clear();
         pCB->queryToStateMap.clear();
         pCB->activeQueries.clear();
@@ -3677,11 +3914,15 @@
         pCB->eventUpdates.clear();
         pCB->queryUpdates.clear();
 
+        // Remove object bindings
+        for (auto obj : pCB->object_bindings) {
+            removeCommandBufferBinding(dev_data, &obj, pCB);
+        }
         // Remove this cmdBuffer's reference from each FrameBuffer's CB ref list
         for (auto framebuffer : pCB->framebuffers) {
-            auto fbNode = getFramebuffer(dev_data, framebuffer);
-            if (fbNode)
-                fbNode->referencingCmdBuffers.erase(pCB->commandBuffer);
+            auto fb_node = getFramebuffer(dev_data, framebuffer);
+            if (fb_node)
+                fb_node->cb_bindings.erase(pCB);
         }
         pCB->framebuffers.clear();
         pCB->activeFramebuffer = VK_NULL_HANDLE;
@@ -3739,21 +3980,21 @@
 
 // Print the last bound Gfx Pipeline
 static bool printPipeline(layer_data *my_data, const VkCommandBuffer cb) {
-    bool skipCall = false;
+    bool skip_call = false;
     GLOBAL_CB_NODE *pCB = getCBNode(my_data, cb);
     if (pCB) {
         PIPELINE_NODE *pPipeTrav = getPipeline(my_data, pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].pipeline);
         if (!pPipeTrav) {
             // nothing to print
         } else {
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                __LINE__, DRAWSTATE_NONE, "DS", "%s",
-                                vk_print_vkgraphicspipelinecreateinfo(
-                                    reinterpret_cast<const VkGraphicsPipelineCreateInfo *>(&pPipeTrav->graphicsPipelineCI), "{DS}")
-                                    .c_str());
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                 __LINE__, DRAWSTATE_NONE, "DS", "%s",
+                                 vk_print_vkgraphicspipelinecreateinfo(
+                                     reinterpret_cast<const VkGraphicsPipelineCreateInfo *>(&pPipeTrav->graphicsPipelineCI), "{DS}")
+                                     .c_str());
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 static void printCB(layer_data *my_data, const VkCommandBuffer cb) {
@@ -3773,12 +4014,12 @@
 }
 
 static bool synchAndPrintDSConfig(layer_data *my_data, const VkCommandBuffer cb) {
-    bool skipCall = false;
+    bool skip_call = false;
     if (!(my_data->report_data->active_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)) {
-        return skipCall;
+        return skip_call;
     }
-    skipCall |= printPipeline(my_data, cb);
-    return skipCall;
+    skip_call |= printPipeline(my_data, cb);
+    return skip_call;
 }
 
 // Flags validation error if the associated call is made inside a render pass. The apiName
@@ -3839,9 +4080,9 @@
     instance_data->report_data =
         debug_report_create_instance(instance_data->instance_dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount,
                                      pCreateInfo->ppEnabledExtensionNames);
-
     init_core_validation(instance_data, pAllocator);
 
+    instance_data->instance_state = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE());
     ValidateLayerOrdering(*pCreateInfo);
 
     return result;
@@ -3870,30 +4111,101 @@
     layer_data_map.erase(key);
 }
 
-static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
+static void checkDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
     uint32_t i;
     // TBD: Need any locking, in case this function is called at the same time
     // by more than one thread?
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     dev_data->device_extensions.wsi_enabled = false;
 
-    VkLayerDispatchTable *pDisp = dev_data->device_dispatch_table;
-    PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
-    pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
-    pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
-    pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
-    pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
-    pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
-
     for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
             dev_data->device_extensions.wsi_enabled = true;
     }
 }
 
+// Verify that queue family has been properly requested
+bool ValidateRequestedQueueFamilyProperties(layer_data *dev_data, const VkDeviceCreateInfo *create_info) {
+    bool skip_call = false;
+    // First check is app has actually requested queueFamilyProperties
+    if (!dev_data->physical_device_state) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+                             0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
+                             "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices().");
+    } else if (QUERY_DETAILS != dev_data->physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
+        // TODO: This is not called out as an invalid use in the spec so make more informative recommendation.
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                             VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
+                             "DL", "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties().");
+    } else {
+        // Check that the requested queue properties are valid
+        for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
+            uint32_t requestedIndex = create_info->pQueueCreateInfos[i].queueFamilyIndex;
+            if (dev_data->queue_family_properties.size() <=
+                requestedIndex) { // requested index is out of bounds for this physical device
+                skip_call |= log_msg(
+                    dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
+                    __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
+                    "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested.", requestedIndex);
+            } else if (create_info->pQueueCreateInfos[i].queueCount >
+                       dev_data->queue_family_properties[requestedIndex]->queueCount) {
+                skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+                            0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
+                            "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but "
+                            "requested queueCount is %u.",
+                            requestedIndex, dev_data->queue_family_properties[requestedIndex]->queueCount,
+                            create_info->pQueueCreateInfos[i].queueCount);
+            }
+        }
+    }
+    return skip_call;
+}
+
+// Verify that features have been queried and that they are available
+static bool ValidateRequestedFeatures(layer_data *dev_data, const VkPhysicalDeviceFeatures *requested_features) {
+    bool skip_call = false;
+
+    VkBool32 *actual = reinterpret_cast<VkBool32 *>(&(dev_data->physical_device_features));
+    const VkBool32 *requested = reinterpret_cast<const VkBool32 *>(requested_features);
+    // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues
+    //  Need to provide the struct member name with the issue. To do that seems like we'll
+    //  have to loop through each struct member which should be done w/ codegen to keep in synch.
+    uint32_t errors = 0;
+    uint32_t total_bools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
+    for (uint32_t i = 0; i < total_bools; i++) {
+        if (requested[i] > actual[i]) {
+            // TODO: Add index to struct member name helper to be able to include a feature name
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED,
+                "DL", "While calling vkCreateDevice(), requesting feature #%u in VkPhysicalDeviceFeatures struct, "
+                "which is not available on this device.",
+                i);
+            errors++;
+        }
+    }
+    if (errors && (UNCALLED == dev_data->physical_device_state->vkGetPhysicalDeviceFeaturesState)) {
+        // If user didn't request features, notify them that they should
+        // TODO: Verify this against the spec. I believe this is an invalid use of the API and should return an error
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                             VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED,
+                             "DL", "You requested features that are unavailable on this device. You should first query feature "
+                                   "availability by calling vkGetPhysicalDeviceFeatures().");
+    }
+    return skip_call;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
                                             const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
     layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
+    bool skip_call = false;
+
+    // Check that any requested features are available
+    if (pCreateInfo->pEnabledFeatures) {
+        skip_call |= ValidateRequestedFeatures(my_instance_data, pCreateInfo->pEnabledFeatures);
+    }
+    skip_call |= ValidateRequestedQueueFamilyProperties(my_instance_data, pCreateInfo);
+
     VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
 
     assert(chain_info->u.pLayerInfo);
@@ -3921,7 +4233,7 @@
     my_device_data->device = *pDevice;
 
     my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
-    createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+    checkDeviceRegisterExtensions(pCreateInfo, *pDevice);
     // Get physical device limits for this device
     my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_device_data->phys_dev_properties.properties));
     uint32_t count;
@@ -3973,7 +4285,7 @@
     dev_data->queueMap.clear();
     lock.unlock();
 #if MTMERGESOURCE
-    bool skipCall = false;
+    bool skip_call = false;
     lock.lock();
     log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
             (uint64_t)device, __LINE__, MEMTRACK_NONE, "MEM", "Printing List details prior to vkDestroyDevice()");
@@ -3985,14 +4297,14 @@
     DEVICE_MEM_INFO *pInfo = NULL;
     if (!dev_data->memObjMap.empty()) {
         for (auto ii = dev_data->memObjMap.begin(); ii != dev_data->memObjMap.end(); ++ii) {
-            pInfo = &(*ii).second;
-            if (pInfo->allocInfo.allocationSize != 0) {
+            pInfo = (*ii).second.get();
+            if (pInfo->alloc_info.allocationSize != 0) {
                 // Valid Usage: All child objects created on device must have been destroyed prior to destroying device
-                skipCall |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)pInfo->mem, __LINE__, MEMTRACK_MEMORY_LEAK,
-                            "MEM", "Mem Object 0x%" PRIx64 " has not been freed. You should clean up this memory by calling "
-                                   "vkFreeMemory(0x%" PRIx64 ") prior to vkDestroyDevice().",
+                skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            (uint64_t)pInfo->mem, __LINE__, MEMTRACK_MEMORY_LEAK, "MEM",
+                            "Mem Object 0x%" PRIx64 " has not been freed. You should clean up this memory by calling "
+                            "vkFreeMemory(0x%" PRIx64 ") prior to vkDestroyDevice().",
                             (uint64_t)(pInfo->mem), (uint64_t)(pInfo->mem));
             }
         }
@@ -4004,7 +4316,7 @@
     fprintf(stderr, "Device: 0x%p, key: 0x%p\n", device, key);
 #endif
     VkLayerDispatchTable *pDisp = dev_data->device_dispatch_table;
-    if (!skipCall) {
+    if (!skip_call) {
         pDisp->DestroyDevice(device, pAllocator);
     }
 #else
@@ -4061,15 +4373,19 @@
 // Track which resources are in-flight by atomically incrementing their "in_use" count
 static bool validateAndIncrementResources(layer_data *my_data, GLOBAL_CB_NODE *pCB) {
     bool skip_call = false;
+
+    pCB->in_use.fetch_add(1);
+    my_data->globalInFlightCmdBuffers.insert(pCB->commandBuffer);
+
     for (auto drawDataElement : pCB->drawData) {
         for (auto buffer : drawDataElement.buffers) {
-            auto buffer_data = my_data->bufferMap.find(buffer);
-            if (buffer_data == my_data->bufferMap.end()) {
+            auto buffer_node = getBufferNode(my_data, buffer);
+            if (!buffer_node) {
                 skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
                                      (uint64_t)(buffer), __LINE__, DRAWSTATE_INVALID_BUFFER, "DS",
                                      "Cannot submit cmd buffer using deleted buffer 0x%" PRIx64 ".", (uint64_t)(buffer));
             } else {
-                buffer_data->second.in_use.fetch_add(1);
+                buffer_node->in_use.fetch_add(1);
             }
         }
     }
@@ -4085,37 +4401,28 @@
             }
         }
     }
-    for (auto semaphore : pCB->semaphores) {
-        auto semaphoreNode = my_data->semaphoreMap.find(semaphore);
-        if (semaphoreNode == my_data->semaphoreMap.end()) {
-            skip_call |=
-                log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                        reinterpret_cast<uint64_t &>(semaphore), __LINE__, DRAWSTATE_INVALID_SEMAPHORE, "DS",
-                        "Cannot submit cmd buffer using deleted semaphore 0x%" PRIx64 ".", reinterpret_cast<uint64_t &>(semaphore));
-        } else {
-            semaphoreNode->second.in_use.fetch_add(1);
-        }
-    }
     for (auto event : pCB->events) {
-        auto eventNode = my_data->eventMap.find(event);
-        if (eventNode == my_data->eventMap.end()) {
+        auto event_node = getEventNode(my_data, event);
+        if (!event_node) {
             skip_call |=
                 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                         reinterpret_cast<uint64_t &>(event), __LINE__, DRAWSTATE_INVALID_EVENT, "DS",
                         "Cannot submit cmd buffer using deleted event 0x%" PRIx64 ".", reinterpret_cast<uint64_t &>(event));
         } else {
-            eventNode->second.in_use.fetch_add(1);
+            event_node->in_use.fetch_add(1);
         }
     }
     for (auto event : pCB->writeEventsBeforeWait) {
-        auto eventNode = my_data->eventMap.find(event);
-        eventNode->second.write_in_use++;
+        auto event_node = getEventNode(my_data, event);
+        if (event_node)
+            event_node->write_in_use++;
     }
     return skip_call;
 }
 
 // Note: This function assumes that the global lock is held by the calling
 // thread.
+// TODO: untangle this.
 static bool cleanInFlightCmdBuffer(layer_data *my_data, VkCommandBuffer cmdBuffer) {
     bool skip_call = false;
     GLOBAL_CB_NODE *pCB = getCBNode(my_data, cmdBuffer);
@@ -4134,6 +4441,8 @@
     }
     return skip_call;
 }
+
+// TODO: nuke this completely.
 // Decrement cmd_buffer in_use and if it goes to 0 remove cmd_buffer from globalInFlightCmdBuffers
 static inline void removeInFlightCmdBuffer(layer_data *dev_data, VkCommandBuffer cmd_buffer) {
     // Pull it off of global list initially, but if we find it in any other queue list, add it back in
@@ -4144,45 +4453,48 @@
     }
 }
 
-static void decrementResources(layer_data *my_data, VkCommandBuffer cmdBuffer) {
-    GLOBAL_CB_NODE *pCB = getCBNode(my_data, cmdBuffer);
-    for (auto drawDataElement : pCB->drawData) {
-        for (auto buffer : drawDataElement.buffers) {
-            auto buffer_data = my_data->bufferMap.find(buffer);
-            if (buffer_data != my_data->bufferMap.end()) {
-                buffer_data->second.in_use.fetch_sub(1);
+static void decrementResources(layer_data *my_data, CB_SUBMISSION *submission) {
+    for (auto cb : submission->cbs) {
+        auto pCB = getCBNode(my_data, cb);
+        for (auto drawDataElement : pCB->drawData) {
+            for (auto buffer : drawDataElement.buffers) {
+                auto buffer_node = getBufferNode(my_data, buffer);
+                if (buffer_node) {
+                    buffer_node->in_use.fetch_sub(1);
+                }
             }
         }
-    }
-    for (uint32_t i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; ++i) {
-        for (auto set : pCB->lastBound[i].uniqueBoundSets) {
-            set->in_use.fetch_sub(1);
+        for (uint32_t i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; ++i) {
+            for (auto set : pCB->lastBound[i].uniqueBoundSets) {
+                set->in_use.fetch_sub(1);
+            }
+        }
+        for (auto event : pCB->events) {
+            auto eventNode = my_data->eventMap.find(event);
+            if (eventNode != my_data->eventMap.end()) {
+                eventNode->second.in_use.fetch_sub(1);
+            }
+        }
+        for (auto event : pCB->writeEventsBeforeWait) {
+            auto eventNode = my_data->eventMap.find(event);
+            if (eventNode != my_data->eventMap.end()) {
+                eventNode->second.write_in_use--;
+            }
+        }
+        for (auto queryStatePair : pCB->queryToStateMap) {
+            my_data->queryToStateMap[queryStatePair.first] = queryStatePair.second;
+        }
+        for (auto eventStagePair : pCB->eventToStageMap) {
+            my_data->eventMap[eventStagePair.first].stageMask = eventStagePair.second;
         }
     }
-    for (auto semaphore : pCB->semaphores) {
-        auto semaphoreNode = my_data->semaphoreMap.find(semaphore);
-        if (semaphoreNode != my_data->semaphoreMap.end()) {
-            semaphoreNode->second.in_use.fetch_sub(1);
+
+    for (auto semaphore : submission->semaphores) {
+        auto pSemaphore = getSemaphoreNode(my_data, semaphore);
+        if (pSemaphore) {
+            pSemaphore->in_use.fetch_sub(1);
         }
     }
-    for (auto event : pCB->events) {
-        auto eventNode = my_data->eventMap.find(event);
-        if (eventNode != my_data->eventMap.end()) {
-            eventNode->second.in_use.fetch_sub(1);
-        }
-    }
-    for (auto event : pCB->writeEventsBeforeWait) {
-        auto eventNode = my_data->eventMap.find(event);
-        if (eventNode != my_data->eventMap.end()) {
-            eventNode->second.write_in_use--;
-        }
-    }
-    for (auto queryStatePair : pCB->queryToStateMap) {
-        my_data->queryToStateMap[queryStatePair.first] = queryStatePair.second;
-    }
-    for (auto eventStagePair : pCB->eventToStageMap) {
-        my_data->eventMap[eventStagePair.first].stageMask = eventStagePair.second;
-    }
 }
 // For fenceCount fences in pFences, mark fence signaled, decrement in_use, and call
 //  decrementResources for all priorFences and cmdBuffers associated with fence.
@@ -4190,32 +4502,33 @@
     bool skip_call = false;
     std::vector<std::pair<VkFence, FENCE_NODE *>> fence_pairs;
     for (uint32_t i = 0; i < fenceCount; ++i) {
-        auto fence_data = my_data->fenceMap.find(pFences[i]);
-        if (fence_data == my_data->fenceMap.end() || !fence_data->second.needsSignaled)
-            return skip_call;
-        fence_data->second.needsSignaled = false;
-        if (fence_data->second.in_use.load()) {
-            fence_pairs.push_back(std::make_pair(fence_data->first, &fence_data->second));
-            fence_data->second.in_use.fetch_sub(1);
+        auto pFence = getFenceNode(my_data, pFences[i]);
+        if (!pFence || pFence->state != FENCE_INFLIGHT)
+            continue;
+
+        fence_pairs.emplace_back(pFences[i], pFence);
+        pFence->state = FENCE_RETIRED;
+
+        decrementResources(my_data, static_cast<uint32_t>(pFence->priorFences.size()),
+                           pFence->priorFences.data());
+        for (auto & submission : pFence->submissions) {
+            decrementResources(my_data, &submission);
+            for (auto cb : submission.cbs) {
+                skip_call |= cleanInFlightCmdBuffer(my_data, cb);
+                removeInFlightCmdBuffer(my_data, cb);
+            }
         }
-        decrementResources(my_data, static_cast<uint32_t>(fence_data->second.priorFences.size()),
-                           fence_data->second.priorFences.data());
-        for (auto cmdBuffer : fence_data->second.cmdBuffers) {
-            decrementResources(my_data, cmdBuffer);
-            skip_call |= cleanInFlightCmdBuffer(my_data, cmdBuffer);
-            removeInFlightCmdBuffer(my_data, cmdBuffer);
-        }
-        fence_data->second.cmdBuffers.clear();
-        fence_data->second.priorFences.clear();
+        pFence->submissions.clear();
+        pFence->priorFences.clear();
     }
     for (auto fence_pair : fence_pairs) {
         for (auto queue : fence_pair.second->queues) {
-            auto queue_pair = my_data->queueMap.find(queue);
-            if (queue_pair != my_data->queueMap.end()) {
+            auto pQueue = getQueueNode(my_data, queue);
+            if (pQueue) {
                 auto last_fence_data =
-                    std::find(queue_pair->second.lastFences.begin(), queue_pair->second.lastFences.end(), fence_pair.first);
-                if (last_fence_data != queue_pair->second.lastFences.end())
-                    queue_pair->second.lastFences.erase(last_fence_data);
+                    std::find(pQueue->lastFences.begin(), pQueue->lastFences.end(), fence_pair.first);
+                if (last_fence_data != pQueue->lastFences.end())
+                    pQueue->lastFences.erase(last_fence_data);
             }
         }
         for (auto& fence_data : my_data->fenceMap) {
@@ -4232,12 +4545,14 @@
     bool skip_call = false;
     auto queue_data = my_data->queueMap.find(queue);
     if (queue_data != my_data->queueMap.end()) {
-        for (auto cmdBuffer : queue_data->second.untrackedCmdBuffers) {
-            decrementResources(my_data, cmdBuffer);
-            skip_call |= cleanInFlightCmdBuffer(my_data, cmdBuffer);
-            removeInFlightCmdBuffer(my_data, cmdBuffer);
+        for (auto & submission : queue_data->second.untrackedSubmissions) {
+            decrementResources(my_data, &submission);
+            for (auto cb : submission.cbs) {
+                skip_call |= cleanInFlightCmdBuffer(my_data, cb);
+                removeInFlightCmdBuffer(my_data, cb);
+            }
         }
-        queue_data->second.untrackedCmdBuffers.clear();
+        queue_data->second.untrackedSubmissions.clear();
         skip_call |= decrementResources(my_data, static_cast<uint32_t>(queue_data->second.lastFences.size()),
                                         queue_data->second.lastFences.data());
     }
@@ -4252,38 +4567,40 @@
     if (queue == other_queue) {
         return;
     }
-    auto queue_data = dev_data->queueMap.find(queue);
-    auto other_queue_data = dev_data->queueMap.find(other_queue);
-    if (queue_data == dev_data->queueMap.end() || other_queue_data == dev_data->queueMap.end()) {
+    auto pQueue = getQueueNode(dev_data, queue);
+    auto pOtherQueue = getQueueNode(dev_data, other_queue);
+    if (!pQueue || !pOtherQueue) {
         return;
     }
-    for (auto fenceInner : other_queue_data->second.lastFences) {
-        queue_data->second.lastFences.push_back(fenceInner);
-        auto fence_node = dev_data->fenceMap.find(fenceInner);
-        if (fence_node != dev_data->fenceMap.end()) {
-            fence_node->second.queues.insert(other_queue_data->first);
-        }
+    for (auto fenceInner : pOtherQueue->lastFences) {
+        pQueue->lastFences.push_back(fenceInner);
+        auto pFenceInner = getFenceNode(dev_data, fenceInner);
+        if (pFenceInner)
+            pFenceInner->queues.insert(other_queue);
     }
-    if (fence != VK_NULL_HANDLE) {
-        auto fence_data = dev_data->fenceMap.find(fence);
-        if (fence_data == dev_data->fenceMap.end()) {
-            return;
+    // TODO: Stealing the untracked CBs out of the signaling queue isn't really
+    // correct. A subsequent submission + wait, or a QWI on that queue, or
+    // another semaphore dependency to a third queue may /all/ provide
+    // suitable proof that the work we're stealing here has completed on the
+    // device, but we've lost that information by moving the tracking between
+    // queues.
+    auto pFence = getFenceNode(dev_data, fence);
+    if (pFence) {
+        for (auto submission : pOtherQueue->untrackedSubmissions) {
+            pFence->submissions.push_back(submission);
         }
-        for (auto cmdbuffer : other_queue_data->second.untrackedCmdBuffers) {
-            fence_data->second.cmdBuffers.push_back(cmdbuffer);
-        }
-        other_queue_data->second.untrackedCmdBuffers.clear();
+        pOtherQueue->untrackedSubmissions.clear();
     } else {
-        for (auto cmdbuffer : other_queue_data->second.untrackedCmdBuffers) {
-            queue_data->second.untrackedCmdBuffers.push_back(cmdbuffer);
+        for (auto submission : pOtherQueue->untrackedSubmissions) {
+            pQueue->untrackedSubmissions.push_back(submission);
         }
-        other_queue_data->second.untrackedCmdBuffers.clear();
+        pOtherQueue->untrackedSubmissions.clear();
     }
-    for (auto eventStagePair : other_queue_data->second.eventToStageMap) {
-        queue_data->second.eventToStageMap[eventStagePair.first] = eventStagePair.second;
+    for (auto eventStagePair : pOtherQueue->eventToStageMap) {
+        pQueue->eventToStageMap[eventStagePair.first] = eventStagePair.second;
     }
-    for (auto queryStatePair : other_queue_data->second.queryToStateMap) {
-        queue_data->second.queryToStateMap[queryStatePair.first] = queryStatePair.second;
+    for (auto queryStatePair : pOtherQueue->queryToStateMap) {
+        pQueue->queryToStateMap[queryStatePair.first] = queryStatePair.second;
     }
 }
 
@@ -4295,72 +4612,23 @@
 // waited on, prior fences on that queue are also considered to have been waited on. When a fence is
 // waited on (either via a queue, device or fence), we free the cmd buffers for that fence and
 // recursively call with the prior fences.
-static void trackCommandBuffers(layer_data *my_data, VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
-                                VkFence fence) {
-    auto queue_data = my_data->queueMap.find(queue);
-    if (fence != VK_NULL_HANDLE) {
-        vector<VkFence> prior_fences;
-        auto fence_data = my_data->fenceMap.find(fence);
-        if (fence_data == my_data->fenceMap.end()) {
-            return;
-        }
-        fence_data->second.cmdBuffers.clear();
-        if (queue_data != my_data->queueMap.end()) {
-            prior_fences = queue_data->second.lastFences;
-            queue_data->second.lastFences.clear();
-            queue_data->second.lastFences.push_back(fence);
-            for (auto cmdbuffer : queue_data->second.untrackedCmdBuffers) {
-                fence_data->second.cmdBuffers.push_back(cmdbuffer);
-            }
-            queue_data->second.untrackedCmdBuffers.clear();
-        }
-        fence_data->second.priorFences = prior_fences;
-        fence_data->second.needsSignaled = true;
-        fence_data->second.queues.insert(queue);
-        fence_data->second.in_use.fetch_add(1);
-        for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
-            const VkSubmitInfo *submit = &pSubmits[submit_idx];
-            for (uint32_t i = 0; i < submit->commandBufferCount; ++i) {
-                for (auto secondaryCmdBuffer : my_data->commandBufferMap[submit->pCommandBuffers[i]]->secondaryCommandBuffers) {
-                    fence_data->second.cmdBuffers.push_back(secondaryCmdBuffer);
-                }
-                fence_data->second.cmdBuffers.push_back(submit->pCommandBuffers[i]);
-            }
-        }
-    } else {
-        if (queue_data != my_data->queueMap.end()) {
-            for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
-                const VkSubmitInfo *submit = &pSubmits[submit_idx];
-                for (uint32_t i = 0; i < submit->commandBufferCount; ++i) {
-                    for (auto secondaryCmdBuffer : my_data->commandBufferMap[submit->pCommandBuffers[i]]->secondaryCommandBuffers) {
-                        queue_data->second.untrackedCmdBuffers.push_back(secondaryCmdBuffer);
-                    }
-                    queue_data->second.untrackedCmdBuffers.push_back(submit->pCommandBuffers[i]);
-                }
-            }
-        }
-    }
-}
 
-static void markCommandBuffersInFlight(layer_data *my_data, VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
-                                       VkFence fence) {
-    auto queue_data = my_data->queueMap.find(queue);
-    if (queue_data != my_data->queueMap.end()) {
-        for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
-            const VkSubmitInfo *submit = &pSubmits[submit_idx];
-            for (uint32_t i = 0; i < submit->commandBufferCount; ++i) {
-                // Add cmdBuffers to the global set and increment count
-                GLOBAL_CB_NODE *pCB = getCBNode(my_data, submit->pCommandBuffers[i]);
-                for (auto secondaryCmdBuffer : my_data->commandBufferMap[submit->pCommandBuffers[i]]->secondaryCommandBuffers) {
-                    my_data->globalInFlightCmdBuffers.insert(secondaryCmdBuffer);
-                    GLOBAL_CB_NODE *pSubCB = getCBNode(my_data, secondaryCmdBuffer);
-                    pSubCB->in_use.fetch_add(1);
-                }
-                my_data->globalInFlightCmdBuffers.insert(submit->pCommandBuffers[i]);
-                pCB->in_use.fetch_add(1);
-            }
-        }
-    }
+
+// Submit a fence to a queue, delimiting previous fences and previous untracked
+// work by it.
+static void
+SubmitFence(QUEUE_NODE *pQueue, FENCE_NODE *pFence)
+{
+    assert(!pFence->priorFences.size());
+    assert(!pFence->submissions.size());
+
+    std::swap(pFence->priorFences, pQueue->lastFences);
+    std::swap(pFence->submissions, pQueue->untrackedSubmissions);
+
+    pFence->queues.insert(pQueue->queue);
+    pFence->state = FENCE_INFLIGHT;
+
+    pQueue->lastFences.push_back(pFence->fence);
 }
 
 static bool validateCommandBufferSimultaneousUse(layer_data *dev_data, GLOBAL_CB_NODE *pCB) {
@@ -4377,90 +4645,76 @@
 }
 
 static bool validateCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB) {
-    bool skipCall = false;
+    bool skip_call = false;
     // Validate ONE_TIME_SUBMIT_BIT CB is not being submitted more than once
     if ((pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) && (pCB->submitCount > 1)) {
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
-                            __LINE__, DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS",
-                            "CB 0x%" PRIxLEAST64 " was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT "
-                            "set, but has been submitted 0x%" PRIxLEAST64 " times.",
-                            (uint64_t)(pCB->commandBuffer), pCB->submitCount);
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                             0, __LINE__, DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS",
+                             "CB 0x%" PRIxLEAST64 " was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT "
+                             "set, but has been submitted 0x%" PRIxLEAST64 " times.",
+                             (uint64_t)(pCB->commandBuffer), pCB->submitCount);
     }
     // Validate that cmd buffers have been updated
     if (CB_RECORDED != pCB->state) {
         if (CB_INVALID == pCB->state) {
             // Inform app of reason CB invalid
-            bool causeReported = false;
-            if (!pCB->destroyedSets.empty()) {
-                std::stringstream set_string;
-                for (auto set : pCB->destroyedSets)
-                    set_string << " " << set;
+            for (auto obj : pCB->broken_bindings) {
+                const char *type_str = object_type_to_string(obj.type);
+                // Descriptor sets are a special case that can be either destroyed or updated to invalidated a CB
+                const char *cause_str =
+                    (obj.type == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT) ? "destroyed or updated" : "destroyed";
 
-                skipCall |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            (uint64_t)(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
-                            "You are submitting command buffer 0x%" PRIxLEAST64
-                            " that is invalid because it had the following bound descriptor set(s) destroyed: %s",
-                            (uint64_t)(pCB->commandBuffer), set_string.str().c_str());
-                causeReported = true;
-            }
-            if (!pCB->updatedSets.empty()) {
-                std::stringstream set_string;
-                for (auto set : pCB->updatedSets)
-                    set_string << " " << set;
-
-                skipCall |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            (uint64_t)(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
-                            "You are submitting command buffer 0x%" PRIxLEAST64
-                            " that is invalid because it had the following bound descriptor set(s) updated: %s",
-                            (uint64_t)(pCB->commandBuffer), set_string.str().c_str());
-                causeReported = true;
-            }
-            if (!pCB->destroyedFramebuffers.empty()) {
-                std::stringstream fb_string;
-                for (auto fb : pCB->destroyedFramebuffers)
-                    fb_string << " " << fb;
-
-                skipCall |=
+                skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             reinterpret_cast<uint64_t &>(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
-                            "You are submitting command buffer 0x%" PRIxLEAST64 " that is invalid because it had the following "
-                            "referenced framebuffers destroyed: %s",
-                            reinterpret_cast<uint64_t &>(pCB->commandBuffer), fb_string.str().c_str());
-                causeReported = true;
-            }
-            // TODO : This is defensive programming to make sure an error is
-            //  flagged if we hit this INVALID cmd buffer case and none of the
-            //  above cases are hit. As the number of INVALID cases grows, this
-            //  code should be updated to seemlessly handle all the cases.
-            if (!causeReported) {
-                skipCall |= log_msg(
-                    dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                    reinterpret_cast<uint64_t &>(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
-                    "You are submitting command buffer 0x%" PRIxLEAST64 " that is invalid due to an unknown cause. Validation "
-                    "should "
-                    "be improved to report the exact cause.",
-                    reinterpret_cast<uint64_t &>(pCB->commandBuffer));
+                            "You are submitting command buffer 0x%" PRIxLEAST64 " that is invalid because bound %s 0x%" PRIxLEAST64
+                            " was %s.",
+                            reinterpret_cast<uint64_t &>(pCB->commandBuffer), type_str, obj.handle, cause_str);
             }
         } else { // Flag error for using CB w/o vkEndCommandBuffer() called
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)(pCB->commandBuffer), __LINE__, DRAWSTATE_NO_END_COMMAND_BUFFER, "DS",
                         "You must call vkEndCommandBuffer() on CB 0x%" PRIxLEAST64 " before this call to vkQueueSubmit()!",
                         (uint64_t)(pCB->commandBuffer));
         }
     }
-    return skipCall;
+    return skip_call;
+}
+
+// Validate that queueFamilyIndices of primary command buffers match this queue
+// Secondary command buffers were previously validated in vkCmdExecuteCommands().
+static bool validateQueueFamilyIndices(layer_data *dev_data, GLOBAL_CB_NODE *pCB, VkQueue queue) {
+    bool skip_call = false;
+    auto pPool = getCommandPoolNode(dev_data, pCB->createInfo.commandPool);
+    auto queue_node = getQueueNode(dev_data, queue);
+
+    if (pPool && queue_node && (pPool->queueFamilyIndex != queue_node->queueFamilyIndex)) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+            reinterpret_cast<uint64_t>(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUEUE_FAMILY, "DS",
+            "vkQueueSubmit: Primary command buffer 0x%" PRIxLEAST64
+            " created in queue family %d is being submitted on queue 0x%" PRIxLEAST64 " from queue family %d.",
+            reinterpret_cast<uint64_t>(pCB->commandBuffer), pPool->queueFamilyIndex,
+            reinterpret_cast<uint64_t>(queue), queue_node->queueFamilyIndex);
+    }
+
+    return skip_call;
 }
 
 static bool validatePrimaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB) {
     // Track in-use for resources off of primary and any secondary CBs
-    bool skipCall = validateAndIncrementResources(dev_data, pCB);
+    bool skip_call = false;
+
+    // If USAGE_SIMULTANEOUS_USE_BIT not set then CB cannot already be executing
+    // on device
+    skip_call |= validateCommandBufferSimultaneousUse(dev_data, pCB);
+
+    skip_call |= validateAndIncrementResources(dev_data, pCB);
+
     if (!pCB->secondaryCommandBuffers.empty()) {
         for (auto secondaryCmdBuffer : pCB->secondaryCommandBuffers) {
-            skipCall |= validateAndIncrementResources(dev_data, dev_data->commandBufferMap[secondaryCmdBuffer]);
             GLOBAL_CB_NODE *pSubCB = getCBNode(dev_data, secondaryCmdBuffer);
+            skip_call |= validateAndIncrementResources(dev_data, pSubCB);
             if ((pSubCB->primaryCommandBuffer != pCB->commandBuffer) &&
                 !(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) {
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
@@ -4474,57 +4728,88 @@
             }
         }
     }
-    skipCall |= validateCommandBufferState(dev_data, pCB);
-    // If USAGE_SIMULTANEOUS_USE_BIT not set then CB cannot already be executing
-    // on device
-    skipCall |= validateCommandBufferSimultaneousUse(dev_data, pCB);
-    return skipCall;
+
+    skip_call |= validateCommandBufferState(dev_data, pCB);
+
+    return skip_call;
 }
 
+static bool
+ValidateFenceForSubmit(layer_data *dev_data, FENCE_NODE *pFence)
+{
+    bool skip_call = false;
+
+    if (pFence) {
+        if (pFence->state == FENCE_INFLIGHT) {
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
+                                 (uint64_t)(pFence->fence), __LINE__, DRAWSTATE_INVALID_FENCE, "DS",
+                                 "Fence 0x%" PRIx64 " is already in use by another submission.", (uint64_t)(pFence->fence));
+        }
+
+        else if (pFence->state == FENCE_RETIRED) {
+            skip_call |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
+                        reinterpret_cast<uint64_t &>(pFence->fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
+                        "Fence 0x%" PRIxLEAST64 " submitted in SIGNALED state.  Fences must be reset before being submitted",
+                        reinterpret_cast<uint64_t &>(pFence->fence));
+        }
+    }
+
+    return skip_call;
+}
+
+
 VKAPI_ATTR VkResult VKAPI_CALL
 QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     std::unique_lock<std::mutex> lock(global_lock);
-    // First verify that fence is not in use
-    if (fence != VK_NULL_HANDLE) {
-        if ((submitCount != 0) && dev_data->fenceMap[fence].in_use.load()) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
-                                (uint64_t)(fence), __LINE__, DRAWSTATE_INVALID_FENCE, "DS",
-                                "Fence 0x%" PRIx64 " is already in use by another submission.", (uint64_t)(fence));
-        }
-        if (!dev_data->fenceMap[fence].needsSignaled) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
-                                reinterpret_cast<uint64_t &>(fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
-                                "Fence 0x%" PRIxLEAST64 " submitted in SIGNALED state.  Fences must be reset before being submitted",
-                                reinterpret_cast<uint64_t &>(fence));
-        }
+
+    auto pQueue = getQueueNode(dev_data, queue);
+    auto pFence = getFenceNode(dev_data, fence);
+    skip_call |= ValidateFenceForSubmit(dev_data, pFence);
+
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
     }
+
     // TODO : Review these old print functions and clean up as appropriate
     print_mem_list(dev_data);
     printCBList(dev_data);
-    // Update cmdBuffer-related data structs and mark fence in-use
-    trackCommandBuffers(dev_data, queue, submitCount, pSubmits, fence);
+
+    // Mark the fence in-use.
+    if (pFence) {
+        SubmitFence(pQueue, pFence);
+    }
+
+    // If a fence is supplied, all the command buffers for this call will be
+    // delimited by that fence. Otherwise, they go in the untracked portion of
+    // the queue, and may end up being delimited by a fence supplied in a
+    // subsequent submission.
+    auto & submitTarget = pFence ? pFence->submissions : pQueue->untrackedSubmissions;
+
     // Now verify each individual submit
     std::unordered_set<VkQueue> processed_other_queues;
     for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
         const VkSubmitInfo *submit = &pSubmits[submit_idx];
         vector<VkSemaphore> semaphoreList;
         for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) {
-            const VkSemaphore &semaphore = submit->pWaitSemaphores[i];
+            VkSemaphore semaphore = submit->pWaitSemaphores[i];
+            auto pSemaphore = getSemaphoreNode(dev_data, semaphore);
             semaphoreList.push_back(semaphore);
-            if (dev_data->semaphoreMap.find(semaphore) != dev_data->semaphoreMap.end()) {
-                if (dev_data->semaphoreMap[semaphore].signaled) {
-                    dev_data->semaphoreMap[semaphore].signaled = false;
+            if (pSemaphore) {
+                if (pSemaphore->signaled) {
+                    pSemaphore->signaled = false;
+                    pSemaphore->in_use.fetch_add(1);
                 } else {
-                    skipCall |=
+                    skip_call |=
                         log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
                                 reinterpret_cast<const uint64_t &>(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
                                 "Queue 0x%" PRIx64 " is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.",
                                 reinterpret_cast<uint64_t &>(queue), reinterpret_cast<const uint64_t &>(semaphore));
                 }
-                const VkQueue &other_queue = dev_data->semaphoreMap[semaphore].queue;
+                VkQueue other_queue = pSemaphore->queue;
                 if (other_queue != VK_NULL_HANDLE && !processed_other_queues.count(other_queue)) {
                     updateTrackedCommandBuffers(dev_data, queue, other_queue, fence);
                     processed_other_queues.insert(other_queue);
@@ -4532,48 +4817,57 @@
             }
         }
         for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) {
-            const VkSemaphore &semaphore = submit->pSignalSemaphores[i];
-            if (dev_data->semaphoreMap.find(semaphore) != dev_data->semaphoreMap.end()) {
+            VkSemaphore semaphore = submit->pSignalSemaphores[i];
+            auto pSemaphore = getSemaphoreNode(dev_data, semaphore);
+            if (pSemaphore) {
                 semaphoreList.push_back(semaphore);
-                if (dev_data->semaphoreMap[semaphore].signaled) {
-                    skipCall |=
+                if (pSemaphore->signaled) {
+                    skip_call |=
                         log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
                                 reinterpret_cast<const uint64_t &>(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
                                 "Queue 0x%" PRIx64 " is signaling semaphore 0x%" PRIx64
                                 " that has already been signaled but not waited on by queue 0x%" PRIx64 ".",
                                 reinterpret_cast<uint64_t &>(queue), reinterpret_cast<const uint64_t &>(semaphore),
-                                reinterpret_cast<uint64_t &>(dev_data->semaphoreMap[semaphore].queue));
+                                reinterpret_cast<uint64_t &>(pSemaphore->queue));
                 } else {
-                    dev_data->semaphoreMap[semaphore].signaled = true;
-                    dev_data->semaphoreMap[semaphore].queue = queue;
+                    pSemaphore->signaled = true;
+                    pSemaphore->queue = queue;
+                    pSemaphore->in_use.fetch_add(1);
                 }
             }
         }
+
+        std::vector<VkCommandBuffer> cbs;
+
         for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
             auto pCBNode = getCBNode(dev_data, submit->pCommandBuffers[i]);
-            skipCall |= ValidateCmdBufImageLayouts(dev_data, pCBNode);
+            skip_call |= ValidateCmdBufImageLayouts(dev_data, pCBNode);
             if (pCBNode) {
-                pCBNode->semaphores = semaphoreList;
+                cbs.push_back(submit->pCommandBuffers[i]);
+                for (auto secondaryCmdBuffer : pCBNode->secondaryCommandBuffers) {
+                    cbs.push_back(secondaryCmdBuffer);
+                }
+
                 pCBNode->submitCount++; // increment submit count
-                pCBNode->lastSubmittedFence = fence;
-                pCBNode->lastSubmittedQueue = queue;
-                skipCall |= validatePrimaryCommandBufferState(dev_data, pCBNode);
+                skip_call |= validatePrimaryCommandBufferState(dev_data, pCBNode);
+                skip_call |= validateQueueFamilyIndices(dev_data, pCBNode, queue);
                 // Call submit-time functions to validate/update state
                 for (auto &function : pCBNode->validate_functions) {
-                    skipCall |= function();
+                    skip_call |= function();
                 }
                 for (auto &function : pCBNode->eventUpdates) {
-                    skipCall |= function(queue);
+                    skip_call |= function(queue);
                 }
                 for (auto &function : pCBNode->queryUpdates) {
-                    skipCall |= function(queue);
+                    skip_call |= function(queue);
                 }
             }
         }
+
+        submitTarget.emplace_back(cbs, semaphoreList);
     }
-    markCommandBuffersInFlight(dev_data, queue, submitCount, pSubmits, fence);
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         result = dev_data->device_dispatch_table->QueueSubmit(queue, submitCount, pSubmits, fence);
 
     return result;
@@ -4602,127 +4896,124 @@
     // undefined behavior.
 
     std::unique_lock<std::mutex> lock(global_lock);
-    freeMemObjInfo(my_data, device, mem, false);
+    bool skip_call = freeMemObjInfo(my_data, device, mem, false);
     print_mem_list(my_data);
     printCBList(my_data);
     lock.unlock();
-    my_data->device_dispatch_table->FreeMemory(device, mem, pAllocator);
+    if (!skip_call) {
+        my_data->device_dispatch_table->FreeMemory(device, mem, pAllocator);
+    }
 }
 
-static bool validateMemRange(layer_data *my_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) {
-    bool skipCall = false;
+// Validate that given Map memory range is valid. This means that the memory should not already be mapped,
+//  and that the size of the map range should be:
+//  1. Not zero
+//  2. Within the size of the memory allocation
+static bool ValidateMapMemRange(layer_data *my_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) {
+    bool skip_call = false;
 
     if (size == 0) {
-        skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                           (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
-                           "VkMapMemory: Attempting to map memory range of size zero");
+        skip_call = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
+                            "VkMapMemory: Attempting to map memory range of size zero");
     }
 
     auto mem_element = my_data->memObjMap.find(mem);
     if (mem_element != my_data->memObjMap.end()) {
+        auto mem_info = mem_element->second.get();
         // It is an application error to call VkMapMemory on an object that is already mapped
-        if (mem_element->second.memRange.size != 0) {
-            skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                               (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
-                               "VkMapMemory: Attempting to map memory on an already-mapped object 0x%" PRIxLEAST64, (uint64_t)mem);
+        if (mem_info->mem_range.size != 0) {
+            skip_call = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                                (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
+                                "VkMapMemory: Attempting to map memory on an already-mapped object 0x%" PRIxLEAST64, (uint64_t)mem);
         }
 
         // Validate that offset + size is within object's allocationSize
         if (size == VK_WHOLE_SIZE) {
-            if (offset >= mem_element->second.allocInfo.allocationSize) {
-                skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                   VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP,
-                                   "MEM", "Mapping Memory from 0x%" PRIx64 " to 0x%" PRIx64 " with size of VK_WHOLE_SIZE oversteps total array size 0x%" PRIx64, offset,
-                                   mem_element->second.allocInfo.allocationSize, mem_element->second.allocInfo.allocationSize);
+            if (offset >= mem_info->alloc_info.allocationSize) {
+                skip_call = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                    VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP,
+                                    "MEM", "Mapping Memory from 0x%" PRIx64 " to 0x%" PRIx64
+                                           " with size of VK_WHOLE_SIZE oversteps total array size 0x%" PRIx64,
+                                    offset, mem_info->alloc_info.allocationSize, mem_info->alloc_info.allocationSize);
             }
         } else {
-            if ((offset + size) > mem_element->second.allocInfo.allocationSize) {
-                skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                   VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP,
-                                   "MEM", "Mapping Memory from 0x%" PRIx64 " to 0x%" PRIx64 " oversteps total array size 0x%" PRIx64, offset,
-                                   size + offset, mem_element->second.allocInfo.allocationSize);
+            if ((offset + size) > mem_info->alloc_info.allocationSize) {
+                skip_call =
+                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
+                            "Mapping Memory from 0x%" PRIx64 " to 0x%" PRIx64 " oversteps total array size 0x%" PRIx64, offset,
+                            size + offset, mem_info->alloc_info.allocationSize);
             }
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 static void storeMemRanges(layer_data *my_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) {
-    auto mem_element = my_data->memObjMap.find(mem);
-    if (mem_element != my_data->memObjMap.end()) {
-        MemRange new_range;
-        new_range.offset = offset;
-        new_range.size = size;
-        mem_element->second.memRange = new_range;
+    auto mem_info = getMemObjInfo(my_data, mem);
+    if (mem_info) {
+        mem_info->mem_range.offset = offset;
+        mem_info->mem_range.size = size;
     }
 }
 
 static bool deleteMemRanges(layer_data *my_data, VkDeviceMemory mem) {
-    bool skipCall = false;
-    auto mem_element = my_data->memObjMap.find(mem);
-    if (mem_element != my_data->memObjMap.end()) {
-        if (!mem_element->second.memRange.size) {
+    bool skip_call = false;
+    auto mem_info = getMemObjInfo(my_data, mem);
+    if (mem_info) {
+        if (!mem_info->mem_range.size) {
             // Valid Usage: memory must currently be mapped
-            skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                               (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
-                               "Unmapping Memory without memory being mapped: mem obj 0x%" PRIxLEAST64, (uint64_t)mem);
+            skip_call = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                                (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
+                                "Unmapping Memory without memory being mapped: mem obj 0x%" PRIxLEAST64, (uint64_t)mem);
         }
-        mem_element->second.memRange.size = 0;
-        if (mem_element->second.pData) {
-            free(mem_element->second.pData);
-            mem_element->second.pData = 0;
+        mem_info->mem_range.size = 0;
+        if (mem_info->p_data) {
+            free(mem_info->p_data);
+            mem_info->p_data = 0;
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 static char NoncoherentMemoryFillValue = 0xb;
 
 static void initializeAndTrackMemory(layer_data *dev_data, VkDeviceMemory mem, VkDeviceSize size, void **ppData) {
-    auto mem_element = dev_data->memObjMap.find(mem);
-    if (mem_element != dev_data->memObjMap.end()) {
-        mem_element->second.pDriverData = *ppData;
-        uint32_t index = mem_element->second.allocInfo.memoryTypeIndex;
+    auto mem_info = getMemObjInfo(dev_data, mem);
+    if (mem_info) {
+        mem_info->p_driver_data = *ppData;
+        uint32_t index = mem_info->alloc_info.memoryTypeIndex;
         if (dev_data->phys_dev_mem_props.memoryTypes[index].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
-            mem_element->second.pData = 0;
+            mem_info->p_data = 0;
         } else {
             if (size == VK_WHOLE_SIZE) {
-                size = mem_element->second.allocInfo.allocationSize;
+                size = mem_info->alloc_info.allocationSize;
             }
             size_t convSize = (size_t)(size);
-            mem_element->second.pData = malloc(2 * convSize);
-            memset(mem_element->second.pData, NoncoherentMemoryFillValue, 2 * convSize);
-            *ppData = static_cast<char *>(mem_element->second.pData) + (convSize / 2);
+            mem_info->p_data = malloc(2 * convSize);
+            memset(mem_info->p_data, NoncoherentMemoryFillValue, 2 * convSize);
+            *ppData = static_cast<char *>(mem_info->p_data) + (convSize / 2);
         }
     }
 }
 // Verify that state for fence being waited on is appropriate. That is,
 //  a fence being waited on should not already be signalled and
 //  it should have been submitted on a queue or during acquire next image
-static inline bool verifyWaitFenceState(VkDevice device, VkFence fence, const char *apiCall) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
-    auto pFenceInfo = my_data->fenceMap.find(fence);
-    if (pFenceInfo != my_data->fenceMap.end()) {
-        if (!pFenceInfo->second.firstTimeFlag) {
-            if (!pFenceInfo->second.needsSignaled) {
-                skipCall |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
-                            (uint64_t)fence, __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
-                            "%s specified fence 0x%" PRIxLEAST64 " already in SIGNALED state.", apiCall, (uint64_t)fence);
-            }
-            if (pFenceInfo->second.queues.empty() && !pFenceInfo->second.swapchain) { // Checking status of unsubmitted fence
-                skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
-                                    reinterpret_cast<uint64_t &>(fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
-                                    "%s called for fence 0x%" PRIxLEAST64 " which has not been submitted on a Queue or during "
-                                    "acquire next image.",
-                                    apiCall, reinterpret_cast<uint64_t &>(fence));
-            }
-        } else {
-            pFenceInfo->second.firstTimeFlag = false;
+static inline bool verifyWaitFenceState(layer_data *dev_data, VkFence fence, const char *apiCall) {
+    bool skip_call = false;
+
+    auto pFence = getFenceNode(dev_data, fence);
+    if (pFence) {
+        if (pFence->state == FENCE_UNSIGNALED) {
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
+                                 reinterpret_cast<uint64_t &>(fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
+                                 "%s called for fence 0x%" PRIxLEAST64 " which has not been submitted on a Queue or during "
+                                 "acquire next image.",
+                                 apiCall, reinterpret_cast<uint64_t &>(fence));
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
@@ -4732,7 +5023,7 @@
     // Verify fence status of submitted fences
     std::unique_lock<std::mutex> lock(global_lock);
     for (uint32_t i = 0; i < fenceCount; i++) {
-        skip_call |= verifyWaitFenceState(device, pFences[i], "vkWaitForFences");
+        skip_call |= verifyWaitFenceState(dev_data, pFences[i], "vkWaitForFences");
     }
     lock.unlock();
     if (skip_call)
@@ -4758,20 +5049,18 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL GetFenceStatus(VkDevice device, VkFence fence) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    skipCall = verifyWaitFenceState(device, fence, "vkGetFenceStatus");
+    skip_call = verifyWaitFenceState(dev_data, fence, "vkGetFenceStatus");
     lock.unlock();
 
-    if (skipCall)
-        return result;
+    if (skip_call)
+        return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    result = dev_data->device_dispatch_table->GetFenceStatus(device, fence);
-    bool skip_call = false;
+    VkResult result = dev_data->device_dispatch_table->GetFenceStatus(device, fence);
     lock.lock();
     if (result == VK_SUCCESS) {
-        skipCall |= decrementResources(dev_data, 1, &fence);
+        skip_call |= decrementResources(dev_data, 1, &fence);
     }
     lock.unlock();
     if (skip_call)
@@ -4789,7 +5078,8 @@
     auto result = dev_data->queues.emplace(*pQueue);
     if (result.second == true) {
         QUEUE_NODE *pQNode = &dev_data->queueMap[*pQueue];
-        pQNode->device = device;
+        pQNode->queue = *pQueue;
+        pQNode->queueFamilyIndex = queueFamilyIndex;
     }
 }
 
@@ -4820,65 +5110,77 @@
 
 VKAPI_ATTR void VKAPI_CALL DestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
+    bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
     auto fence_pair = dev_data->fenceMap.find(fence);
     if (fence_pair != dev_data->fenceMap.end()) {
-        if (fence_pair->second.in_use.load()) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
-                                (uint64_t)(fence), __LINE__, DRAWSTATE_INVALID_FENCE, "DS",
-                                "Fence 0x%" PRIx64 " is in use by a command buffer.", (uint64_t)(fence));
+        if (fence_pair->second.state == FENCE_INFLIGHT) {
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
+                                 (uint64_t)(fence), __LINE__, DRAWSTATE_INVALID_FENCE, "DS", "Fence 0x%" PRIx64 " is in use.",
+                                 (uint64_t)(fence));
         }
         dev_data->fenceMap.erase(fence_pair);
     }
     lock.unlock();
 
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->DestroyFence(device, fence, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    dev_data->device_dispatch_table->DestroySemaphore(device, semaphore, pAllocator);
-    std::lock_guard<std::mutex> lock(global_lock);
+
+    std::unique_lock<std::mutex> lock(global_lock);
     auto item = dev_data->semaphoreMap.find(semaphore);
     if (item != dev_data->semaphoreMap.end()) {
         if (item->second.in_use.load()) {
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
-                    reinterpret_cast<uint64_t &>(semaphore), __LINE__, DRAWSTATE_INVALID_SEMAPHORE, "DS",
+                    reinterpret_cast<uint64_t &>(semaphore), __LINE__, DRAWSTATE_OBJECT_INUSE, "DS",
                     "Cannot delete semaphore 0x%" PRIx64 " which is in use.", reinterpret_cast<uint64_t &>(semaphore));
         }
         dev_data->semaphoreMap.erase(semaphore);
     }
-    // TODO : Clean up any internal data structures using this obj.
+    lock.unlock();
+    dev_data->device_dispatch_table->DestroySemaphore(device, semaphore, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto event_data = dev_data->eventMap.find(event);
-    if (event_data != dev_data->eventMap.end()) {
-        if (event_data->second.in_use.load()) {
+    auto event_node = getEventNode(dev_data, event);
+    if (event_node) {
+        if (event_node->in_use.load()) {
             skip_call |= log_msg(
                 dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                reinterpret_cast<uint64_t &>(event), __LINE__, DRAWSTATE_INVALID_EVENT, "DS",
+                reinterpret_cast<uint64_t &>(event), __LINE__, DRAWSTATE_OBJECT_INUSE, "DS",
                 "Cannot delete event 0x%" PRIx64 " which is in use by a command buffer.", reinterpret_cast<uint64_t &>(event));
         }
-        dev_data->eventMap.erase(event_data);
+        // Any bound cmd buffers are now invalid
+        invalidateCommandBuffers(event_node->cb_bindings,
+                                 {reinterpret_cast<uint64_t &>(event), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT});
+        dev_data->eventMap.erase(event);
     }
     lock.unlock();
     if (!skip_call)
         dev_data->device_dispatch_table->DestroyEvent(device, event, pAllocator);
-    // TODO : Clean up any internal data structures using this obj.
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator) {
-    get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-        ->device_dispatch_table->DestroyQueryPool(device, queryPool, pAllocator);
-    // TODO : Clean up any internal data structures using this obj.
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    // TODO : Add detection for an in-flight queryPool
+    std::unique_lock<std::mutex> lock(global_lock);
+    auto qp_node = getQueryPoolNode(dev_data, queryPool);
+    if (qp_node) {
+        // Any bound cmd buffers are now invalid
+        invalidateCommandBuffers(qp_node->cb_bindings,
+                                 {reinterpret_cast<uint64_t &>(queryPool), VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT});
+        dev_data->queryPoolMap.erase(queryPool);
+    }
+    lock.unlock();
+    dev_data->device_dispatch_table->DestroyQueryPool(device, queryPool, pAllocator);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
@@ -4956,13 +5258,13 @@
 
 static bool validateIdleBuffer(const layer_data *my_data, VkBuffer buffer) {
     bool skip_call = false;
-    auto buffer_data = my_data->bufferMap.find(buffer);
-    if (buffer_data == my_data->bufferMap.end()) {
+    auto buffer_node = getBufferNode(my_data, buffer);
+    if (!buffer_node) {
         skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
                              (uint64_t)(buffer), __LINE__, DRAWSTATE_DOUBLE_DESTROY, "DS",
                              "Cannot free buffer 0x%" PRIxLEAST64 " that has not been allocated.", (uint64_t)(buffer));
     } else {
-        if (buffer_data->second.in_use.load()) {
+        if (buffer_node->in_use.load()) {
             skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
                                  (uint64_t)(buffer), __LINE__, DRAWSTATE_OBJECT_INUSE, "DS",
                                  "Cannot free buffer 0x%" PRIxLEAST64 " that is in use by a command buffer.", (uint64_t)(buffer));
@@ -5023,55 +5325,56 @@
 VKAPI_ATTR void VKAPI_CALL DestroyBuffer(VkDevice device, VkBuffer buffer,
                                          const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    if (!validateIdleBuffer(dev_data, buffer) && !skipCall) {
+    if (!validateIdleBuffer(dev_data, buffer)) {
+        // Clean up memory binding and range information for buffer
+        auto buff_node = getBufferNode(dev_data, buffer);
+        if (buff_node) {
+            // Any bound cmd buffers are now invalid
+            invalidateCommandBuffers(buff_node->cb_bindings,
+                                     {reinterpret_cast<uint64_t &>(buff_node->buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT});
+            auto mem_info = getMemObjInfo(dev_data, buff_node->mem);
+            if (mem_info) {
+                remove_memory_ranges(reinterpret_cast<uint64_t &>(buffer), buff_node->mem, mem_info->buffer_ranges);
+            }
+            clear_object_binding(dev_data, reinterpret_cast<uint64_t &>(buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+            dev_data->bufferMap.erase(buff_node->buffer);
+        }
         lock.unlock();
         dev_data->device_dispatch_table->DestroyBuffer(device, buffer, pAllocator);
-        lock.lock();
-    }
-    // Clean up memory binding and range information for buffer
-    const auto &bufferEntry = dev_data->bufferMap.find(buffer);
-    if (bufferEntry != dev_data->bufferMap.end()) {
-        const auto &memEntry = dev_data->memObjMap.find(bufferEntry->second.mem);
-        if (memEntry != dev_data->memObjMap.end()) {
-            remove_memory_ranges(reinterpret_cast<uint64_t &>(buffer), bufferEntry->second.mem, memEntry->second.bufferRanges);
-        }
-        clear_object_binding(dev_data, reinterpret_cast<uint64_t &>(buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
-        dev_data->bufferMap.erase(bufferEntry);
     }
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    dev_data->device_dispatch_table->DestroyBufferView(device, bufferView, pAllocator);
-    std::lock_guard<std::mutex> lock(global_lock);
+
+    std::unique_lock<std::mutex> lock(global_lock);
     auto item = dev_data->bufferViewMap.find(bufferView);
     if (item != dev_data->bufferViewMap.end()) {
         dev_data->bufferViewMap.erase(item);
     }
+    lock.unlock();
+    dev_data->device_dispatch_table->DestroyBufferView(device, bufferView, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
-    if (!skipCall) {
-        dev_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
-    }
 
-    std::lock_guard<std::mutex> lock(global_lock);
-    const auto &imageEntry = dev_data->imageMap.find(image);
-    if (imageEntry != dev_data->imageMap.end()) {
+    std::unique_lock<std::mutex> lock(global_lock);
+    auto img_node = getImageNode(dev_data, image);
+    if (img_node) {
+        // Any bound cmd buffers are now invalid
+        invalidateCommandBuffers(img_node->cb_bindings,
+                                 {reinterpret_cast<uint64_t &>(img_node->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT});
         // Clean up memory mapping, bindings and range references for image
-        auto memEntry = dev_data->memObjMap.find(imageEntry->second.mem);
-        if (memEntry != dev_data->memObjMap.end()) {
-            remove_memory_ranges(reinterpret_cast<uint64_t &>(image), imageEntry->second.mem, memEntry->second.imageRanges);
+        auto mem_info = getMemObjInfo(dev_data, img_node->mem);
+        if (mem_info) {
+            remove_memory_ranges(reinterpret_cast<uint64_t &>(image), img_node->mem, mem_info->image_ranges);
             clear_object_binding(dev_data, reinterpret_cast<uint64_t &>(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
-            memEntry->second.image = VK_NULL_HANDLE;
         }
         // Remove image from imageMap
-        dev_data->imageMap.erase(imageEntry);
+        dev_data->imageMap.erase(img_node->image);
     }
     const auto& subEntry = dev_data->imageSubresourceMap.find(image);
     if (subEntry != dev_data->imageSubresourceMap.end()) {
@@ -5080,6 +5383,22 @@
         }
         dev_data->imageSubresourceMap.erase(subEntry);
     }
+    lock.unlock();
+    dev_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
+}
+
+static bool ValidateMemoryTypes(const layer_data *dev_data, const DEVICE_MEM_INFO *mem_info, const uint32_t memory_type_bits,
+                                  const char *funcName) {
+    bool skip_call = false;
+    if (((1 << mem_info->alloc_info.memoryTypeIndex) & memory_type_bits) == 0) {
+        skip_call = log_msg(
+            dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+            reinterpret_cast<const uint64_t &>(mem_info->mem), __LINE__, MEMTRACK_INVALID_MEM_TYPE, "MT",
+            "%s(): MemoryRequirements->memoryTypeBits (0x%X) for this object type are not compatible with the memory "
+            "type (0x%X) of this memory object 0x%" PRIx64 ".",
+            funcName, memory_type_bits, mem_info->alloc_info.memoryTypeIndex, reinterpret_cast<const uint64_t &>(mem_info->mem));
+    }
+    return skip_call;
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
@@ -5089,26 +5408,27 @@
     std::unique_lock<std::mutex> lock(global_lock);
     // Track objects tied to memory
     uint64_t buffer_handle = (uint64_t)(buffer);
-    bool skipCall =
-        set_mem_binding(dev_data, mem, buffer_handle, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "vkBindBufferMemory");
-    auto buffer_node = dev_data->bufferMap.find(buffer);
-    if (buffer_node != dev_data->bufferMap.end()) {
-        buffer_node->second.mem = mem;
+    bool skip_call = set_mem_binding(dev_data, mem, buffer_handle, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "vkBindBufferMemory");
+    auto buffer_node = getBufferNode(dev_data, buffer);
+    if (buffer_node) {
         VkMemoryRequirements memRequirements;
         dev_data->device_dispatch_table->GetBufferMemoryRequirements(device, buffer, &memRequirements);
+        buffer_node->mem = mem;
+        buffer_node->memOffset = memoryOffset;
+        buffer_node->memSize = memRequirements.size;
 
         // Track and validate bound memory range information
-        const auto &memEntry = dev_data->memObjMap.find(mem);
-        if (memEntry != dev_data->memObjMap.end()) {
+        auto mem_info = getMemObjInfo(dev_data, mem);
+        if (mem_info) {
             const MEMORY_RANGE range =
-                insert_memory_ranges(buffer_handle, mem, memoryOffset, memRequirements, memEntry->second.bufferRanges);
-            skipCall |=
-                validate_memory_range(dev_data, memEntry->second.imageRanges, range, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+                insert_memory_ranges(buffer_handle, mem, memoryOffset, memRequirements, mem_info->buffer_ranges);
+            skip_call |= validate_memory_range(dev_data, mem_info->image_ranges, range, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+            skip_call |= ValidateMemoryTypes(dev_data, mem_info, memRequirements.memoryTypeBits, "BindBufferMemory");
         }
 
         // Validate memory requirements alignment
         if (vk_safe_modulo(memoryOffset, memRequirements.alignment) != 0) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
                         __LINE__, DRAWSTATE_INVALID_BUFFER_MEMORY_OFFSET, "DS",
                         "vkBindBufferMemory(): memoryOffset is 0x%" PRIxLEAST64 " but must be an integer multiple of the "
@@ -5116,44 +5436,45 @@
                         ", returned from a call to vkGetBufferMemoryRequirements with buffer",
                         memoryOffset, memRequirements.alignment);
         }
+
         // Validate device limits alignments
-        VkBufferUsageFlags usage = dev_data->bufferMap[buffer].createInfo.usage;
-        if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
-            if (vk_safe_modulo(memoryOffset, dev_data->phys_dev_properties.properties.limits.minTexelBufferOffsetAlignment) != 0) {
-                skipCall |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
-                            0, __LINE__, DRAWSTATE_INVALID_TEXEL_BUFFER_OFFSET, "DS",
-                            "vkBindBufferMemory(): memoryOffset is 0x%" PRIxLEAST64 " but must be a multiple of "
-                            "device limit minTexelBufferOffsetAlignment 0x%" PRIxLEAST64,
-                            memoryOffset, dev_data->phys_dev_properties.properties.limits.minTexelBufferOffsetAlignment);
-            }
-        }
-        if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) {
-            if (vk_safe_modulo(memoryOffset, dev_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment) !=
-                0) {
-                skipCall |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
-                            0, __LINE__, DRAWSTATE_INVALID_UNIFORM_BUFFER_OFFSET, "DS",
-                            "vkBindBufferMemory(): memoryOffset is 0x%" PRIxLEAST64 " but must be a multiple of "
-                            "device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64,
-                            memoryOffset, dev_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment);
-            }
-        }
-        if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) {
-            if (vk_safe_modulo(memoryOffset, dev_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment) !=
-                0) {
-                skipCall |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
-                            0, __LINE__, DRAWSTATE_INVALID_STORAGE_BUFFER_OFFSET, "DS",
-                            "vkBindBufferMemory(): memoryOffset is 0x%" PRIxLEAST64 " but must be a multiple of "
-                            "device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64,
-                            memoryOffset, dev_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment);
+        static const VkBufferUsageFlagBits usage_list[3] = {
+            static_cast<VkBufferUsageFlagBits>(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT),
+            VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+            VK_BUFFER_USAGE_STORAGE_BUFFER_BIT};
+        static const char *memory_type[3] = {"texel",
+                                             "uniform",
+                                             "storage"};
+        static const char *offset_name[3] = {
+            "minTexelBufferOffsetAlignment",
+            "minUniformBufferOffsetAlignment",
+            "minStorageBufferOffsetAlignment"
+        };
+
+        // Keep this one fresh!
+        const VkDeviceSize offset_requirement[3] = {
+            dev_data->phys_dev_properties.properties.limits.minTexelBufferOffsetAlignment,
+            dev_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment,
+            dev_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment
+        };
+        VkBufferUsageFlags usage = dev_data->bufferMap[buffer].get()->createInfo.usage;
+
+        for (int i = 0; i < 3; i++) {
+            if (usage & usage_list[i]) {
+                if (vk_safe_modulo(memoryOffset, offset_requirement[i]) != 0) {
+                    skip_call |=
+                        log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+                                0, __LINE__, DRAWSTATE_INVALID_TEXEL_BUFFER_OFFSET, "DS",
+                                "vkBindBufferMemory(): %s memoryOffset is 0x%" PRIxLEAST64 " but must be a multiple of "
+                                "device limit %s 0x%" PRIxLEAST64,
+                                memory_type[i], memoryOffset, offset_name[i], offset_requirement[i]);
+                }
             }
         }
     }
     print_mem_list(dev_data);
     lock.unlock();
-    if (!skipCall) {
+    if (!skip_call) {
         result = dev_data->device_dispatch_table->BindBufferMemory(device, buffer, mem, memoryOffset);
     }
     return result;
@@ -5177,9 +5498,9 @@
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) {
+    // TODO : Clean up any internal data structures using this obj.
     get_my_data_ptr(get_dispatch_key(device), layer_data_map)
         ->device_dispatch_table->DestroyImageView(device, imageView, pAllocator);
-    // TODO : Clean up any internal data structures using this obj.
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -5195,41 +5516,54 @@
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
-    get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyPipeline(device, pipeline, pAllocator);
-    // TODO : Clean up any internal data structures using this obj.
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    // TODO : Add detection for in-flight pipeline
+    std::unique_lock<std::mutex> lock(global_lock);
+    auto pipe_node = getPipeline(dev_data, pipeline);
+    if (pipe_node) {
+        // Any bound cmd buffers are now invalid
+        invalidateCommandBuffers(pipe_node->cb_bindings,
+                                 {reinterpret_cast<uint64_t &>(pipeline), VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT});
+        dev_data->pipelineMap.erase(pipeline);
+    }
+    lock.unlock();
+    dev_data->device_dispatch_table->DestroyPipeline(device, pipeline, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks *pAllocator) {
-    get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-        ->device_dispatch_table->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
-    // TODO : Clean up any internal data structures using this obj.
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    dev_data->pipelineLayoutMap.erase(pipelineLayout);
+    lock.unlock();
+
+    dev_data->device_dispatch_table->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) {
-    get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroySampler(device, sampler, pAllocator);
     // TODO : Clean up any internal data structures using this obj.
+    get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroySampler(device, sampler, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks *pAllocator) {
+    // TODO : Clean up any internal data structures using this obj.
     get_my_data_ptr(get_dispatch_key(device), layer_data_map)
         ->device_dispatch_table->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
-    // TODO : Clean up any internal data structures using this obj.
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) {
+    // TODO : Clean up any internal data structures using this obj.
     get_my_data_ptr(get_dispatch_key(device), layer_data_map)
         ->device_dispatch_table->DestroyDescriptorPool(device, descriptorPool, pAllocator);
-    // TODO : Clean up any internal data structures using this obj.
 }
 // Verify cmdBuffer in given cb_node is not in global in-flight set, and return skip_call result
 //  If this is a secondary command buffer, then make sure its primary is also in-flight
 //  If primary is not in-flight, then remove secondary from global in-flight set
 // This function is only valid at a point when cmdBuffer is being reset or freed
-static bool checkAndClearCommandBufferInFlight(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const char *action) {
+static bool checkCommandBufferInFlight(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const char *action) {
     bool skip_call = false;
     if (dev_data->globalInFlightCmdBuffers.count(cb_node->commandBuffer)) {
         // Primary CB or secondary where primary is also in-flight is an error
@@ -5240,51 +5574,64 @@
                 reinterpret_cast<const uint64_t &>(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, "DS",
                 "Attempt to %s command buffer (0x%" PRIxLEAST64 ") which is in use.", action,
                 reinterpret_cast<const uint64_t &>(cb_node->commandBuffer));
-        } else { // Secondary CB w/o primary in-flight, remove from in-flight
-            dev_data->globalInFlightCmdBuffers.erase(cb_node->commandBuffer);
         }
     }
     return skip_call;
 }
+
 // Iterate over all cmdBuffers in given commandPool and verify that each is not in use
-static bool checkAndClearCommandBuffersInFlight(layer_data *dev_data, const VkCommandPool commandPool, const char *action) {
+static bool checkCommandBuffersInFlight(layer_data *dev_data, COMMAND_POOL_NODE *pPool, const char *action) {
     bool skip_call = false;
-    auto pool_data = dev_data->commandPoolMap.find(commandPool);
-    if (pool_data != dev_data->commandPoolMap.end()) {
-        for (auto cmd_buffer : pool_data->second.commandBuffers) {
-            if (dev_data->globalInFlightCmdBuffers.count(cmd_buffer)) {
-                skip_call |= checkAndClearCommandBufferInFlight(dev_data, getCBNode(dev_data, cmd_buffer), action);
-            }
+    for (auto cmd_buffer : pPool->commandBuffers) {
+        if (dev_data->globalInFlightCmdBuffers.count(cmd_buffer)) {
+            skip_call |= checkCommandBufferInFlight(dev_data, getCBNode(dev_data, cmd_buffer), action);
         }
     }
     return skip_call;
 }
 
+static void clearCommandBuffersInFlight(layer_data *dev_data, COMMAND_POOL_NODE *pPool) {
+    for (auto cmd_buffer : pPool->commandBuffers) {
+        dev_data->globalInFlightCmdBuffers.erase(cmd_buffer);
+    }
+}
+
 VKAPI_ATTR void VKAPI_CALL
 FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-
     bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
+
     for (uint32_t i = 0; i < commandBufferCount; i++) {
-        auto cb_pair = dev_data->commandBufferMap.find(pCommandBuffers[i]);
-        skip_call |= checkAndClearCommandBufferInFlight(dev_data, cb_pair->second, "free");
+        auto cb_node = getCBNode(dev_data, pCommandBuffers[i]);
         // Delete CB information structure, and remove from commandBufferMap
-        if (cb_pair != dev_data->commandBufferMap.end()) {
+        if (cb_node) {
+            skip_call |= checkCommandBufferInFlight(dev_data, cb_node, "free");
+        }
+    }
+
+    if (skip_call)
+        return;
+
+    auto pPool = getCommandPoolNode(dev_data, commandPool);
+    for (uint32_t i = 0; i < commandBufferCount; i++) {
+        auto cb_node = getCBNode(dev_data, pCommandBuffers[i]);
+        // Delete CB information structure, and remove from commandBufferMap
+        if (cb_node) {
+            dev_data->globalInFlightCmdBuffers.erase(cb_node->commandBuffer);
             // reset prior to delete for data clean-up
-            resetCB(dev_data, (*cb_pair).second->commandBuffer);
-            delete (*cb_pair).second;
-            dev_data->commandBufferMap.erase(cb_pair);
+            resetCB(dev_data, cb_node->commandBuffer);
+            dev_data->commandBufferMap.erase(cb_node->commandBuffer);
+            delete cb_node;
         }
 
         // Remove commandBuffer reference from commandPoolMap
-        dev_data->commandPoolMap[commandPool].commandBuffers.remove(pCommandBuffers[i]);
+        pPool->commandBuffers.remove(pCommandBuffers[i]);
     }
     printCBList(dev_data);
     lock.unlock();
 
-    if (!skip_call)
-        dev_data->device_dispatch_table->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
+    dev_data->device_dispatch_table->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
@@ -5318,96 +5665,119 @@
 VKAPI_ATTR void VKAPI_CALL
 DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
+    bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
     // Verify that command buffers in pool are complete (not in-flight)
-    VkBool32 result = checkAndClearCommandBuffersInFlight(dev_data, commandPool, "destroy command pool with");
-    // Must remove cmdpool from cmdpoolmap, after removing all cmdbuffers in its list from the commandPoolMap
-    auto pool_it = dev_data->commandPoolMap.find(commandPool);
-    if (pool_it != dev_data->commandPoolMap.end()) {
-        for (auto cb : pool_it->second.commandBuffers) {
-            clear_cmd_buf_and_mem_references(dev_data, cb);
-            auto del_cb = dev_data->commandBufferMap.find(cb);
-            delete del_cb->second;                  // delete CB info structure
-            dev_data->commandBufferMap.erase(del_cb); // Remove this command buffer
+    auto pPool = getCommandPoolNode(dev_data, commandPool);
+    skip_call |= checkCommandBuffersInFlight(dev_data, pPool, "destroy command pool with");
+
+    if (skip_call)
+        return;
+    // Must remove cmdpool from cmdpoolmap, after removing all cmdbuffers in its list from the commandBufferMap
+    clearCommandBuffersInFlight(dev_data, pPool);
+    for (auto cb : pPool->commandBuffers) {
+        clear_cmd_buf_and_mem_references(dev_data, cb);
+        auto cb_node = getCBNode(dev_data, cb);
+        // Remove references to this cb_node prior to delete
+        // TODO : Need better solution here, resetCB?
+        for (auto obj : cb_node->object_bindings) {
+            removeCommandBufferBinding(dev_data, &obj, cb_node);
         }
+        for (auto framebuffer : cb_node->framebuffers) {
+            auto fb_node = getFramebuffer(dev_data, framebuffer);
+            if (fb_node)
+                fb_node->cb_bindings.erase(cb_node);
+        }
+        dev_data->commandBufferMap.erase(cb); // Remove this command buffer
+        delete cb_node;                       // delete CB info structure
     }
     dev_data->commandPoolMap.erase(commandPool);
-
     lock.unlock();
 
-    if (result)
-        return;
-
-    if (!skipCall)
-        dev_data->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator);
+    dev_data->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
 ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
 
-    if (checkAndClearCommandBuffersInFlight(dev_data, commandPool, "reset command pool with"))
+    std::unique_lock<std::mutex> lock(global_lock);
+    auto pPool = getCommandPoolNode(dev_data, commandPool);
+    skip_call |= checkCommandBuffersInFlight(dev_data, pPool, "reset command pool with");
+    lock.unlock();
+
+    if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    if (!skipCall)
-        result = dev_data->device_dispatch_table->ResetCommandPool(device, commandPool, flags);
+    VkResult result = dev_data->device_dispatch_table->ResetCommandPool(device, commandPool, flags);
 
     // Reset all of the CBs allocated from this pool
     if (VK_SUCCESS == result) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        auto it = dev_data->commandPoolMap[commandPool].commandBuffers.begin();
-        while (it != dev_data->commandPoolMap[commandPool].commandBuffers.end()) {
-            resetCB(dev_data, (*it));
-            ++it;
+        lock.lock();
+        clearCommandBuffersInFlight(dev_data, pPool);
+        for (auto cmdBuffer : pPool->commandBuffers) {
+            resetCB(dev_data, cmdBuffer);
         }
+        lock.unlock();
     }
     return result;
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL ResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
     for (uint32_t i = 0; i < fenceCount; ++i) {
-        auto fence_item = dev_data->fenceMap.find(pFences[i]);
-        if (fence_item != dev_data->fenceMap.end()) {
-            fence_item->second.needsSignaled = true;
-            fence_item->second.queues.clear();
-            fence_item->second.priorFences.clear();
-            if (fence_item->second.in_use.load()) {
-                skipCall |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
-                            reinterpret_cast<const uint64_t &>(pFences[i]), __LINE__, DRAWSTATE_INVALID_FENCE, "DS",
-                            "Fence 0x%" PRIx64 " is in use by a command buffer.", reinterpret_cast<const uint64_t &>(pFences[i]));
-            }
+        auto pFence = getFenceNode(dev_data, pFences[i]);
+        if (pFence && pFence->state == FENCE_INFLIGHT) {
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
+                                 reinterpret_cast<const uint64_t &>(pFences[i]), __LINE__, DRAWSTATE_INVALID_FENCE, "DS",
+                                 "Fence 0x%" PRIx64 " is in use.", reinterpret_cast<const uint64_t &>(pFences[i]));
         }
     }
     lock.unlock();
-    if (!skipCall)
-        result = dev_data->device_dispatch_table->ResetFences(device, fenceCount, pFences);
+
+    if (skip_call)
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+
+    VkResult result = dev_data->device_dispatch_table->ResetFences(device, fenceCount, pFences);
+
+    if (result == VK_SUCCESS) {
+        lock.lock();
+        for (uint32_t i = 0; i < fenceCount; ++i) {
+            auto pFence = getFenceNode(dev_data, pFences[i]);
+            if (pFence) {
+                pFence->state = FENCE_UNSIGNALED;
+                // TODO: these should really have already been enforced on
+                // INFLIGHT->RETIRED transition.
+                pFence->queues.clear();
+                pFence->priorFences.clear();
+            }
+        }
+        lock.unlock();
+    }
+
     return result;
 }
 
+// For given cb_nodes, invalidate them and track object causing invalidation
+void invalidateCommandBuffers(std::unordered_set<GLOBAL_CB_NODE *> cb_nodes, VK_OBJECT obj) {
+    for (auto cb_node : cb_nodes) {
+        cb_node->state = CB_INVALID;
+        cb_node->broken_bindings.push_back(obj);
+    }
+}
+
 VKAPI_ATTR void VKAPI_CALL
 DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    auto fbNode = dev_data->frameBufferMap.find(framebuffer);
-    if (fbNode != dev_data->frameBufferMap.end()) {
-        for (auto cb : fbNode->second.referencingCmdBuffers) {
-            auto cbNode = dev_data->commandBufferMap.find(cb);
-            if (cbNode != dev_data->commandBufferMap.end()) {
-                // Set CB as invalid and record destroyed framebuffer
-                cbNode->second->state = CB_INVALID;
-                cbNode->second->destroyedFramebuffers.insert(framebuffer);
-            }
-        }
-        delete [] fbNode->second.createInfo.pAttachments;
-        dev_data->frameBufferMap.erase(fbNode);
+    auto fb_node = getFramebuffer(dev_data, framebuffer);
+    if (fb_node) {
+        invalidateCommandBuffers(fb_node->cb_bindings,
+                                 {reinterpret_cast<uint64_t &>(fb_node->framebuffer), VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT});
+        dev_data->frameBufferMap.erase(fb_node->framebuffer);
     }
     lock.unlock();
     dev_data->device_dispatch_table->DestroyFramebuffer(device, framebuffer, pAllocator);
@@ -5416,9 +5786,11 @@
 VKAPI_ATTR void VKAPI_CALL
 DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    dev_data->device_dispatch_table->DestroyRenderPass(device, renderPass, pAllocator);
-    std::lock_guard<std::mutex> lock(global_lock);
+    std::unique_lock<std::mutex> lock(global_lock);
     dev_data->renderPassMap.erase(renderPass);
+    // TODO: leaking all the guts of the renderpass node here!
+    lock.unlock();
+    dev_data->device_dispatch_table->DestroyRenderPass(device, renderPass, pAllocator);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
@@ -5430,23 +5802,39 @@
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
         // TODO : This doesn't create deep copy of pQueueFamilyIndices so need to fix that if/when we want that data to be valid
-        dev_data->bufferMap.insert(std::make_pair(*pBuffer, BUFFER_NODE(pCreateInfo)));
+        dev_data->bufferMap.insert(std::make_pair(*pBuffer, unique_ptr<BUFFER_NODE>(new BUFFER_NODE(*pBuffer, pCreateInfo))));
     }
     return result;
 }
 
+static bool PreCallValidateCreateBufferView(layer_data *dev_data, const VkBufferViewCreateInfo *pCreateInfo) {
+    bool skip_call = false;
+    BUFFER_NODE *buf_node = getBufferNode(dev_data, pCreateInfo->buffer);
+    // If this isn't a sparse buffer, it needs to have memory backing it at CreateBufferView time
+    if (buf_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, buf_node, "vkCreateBufferView()");
+        // In order to create a valid buffer view, the buffer must have been created with at least one of the
+        // following flags:  UNIFORM_TEXEL_BUFFER_BIT or STORAGE_TEXEL_BUFFER_BIT
+        skip_call |= ValidateBufferUsageFlags(dev_data, buf_node,
+                                              VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
+                                              false, "vkCreateBufferView()", "VK_BUFFER_USAGE_[STORAGE|UNIFORM]_TEXEL_BUFFER_BIT");
+    }
+    return skip_call;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
                                                 const VkAllocationCallbacks *pAllocator, VkBufferView *pView) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    bool skip_call = PreCallValidateCreateBufferView(dev_data, pCreateInfo);
+    lock.unlock();
+    if (skip_call)
+        return VK_ERROR_VALIDATION_FAILED_EXT;
     VkResult result = dev_data->device_dispatch_table->CreateBufferView(device, pCreateInfo, pAllocator, pView);
     if (VK_SUCCESS == result) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        dev_data->bufferViewMap[*pView] = VkBufferViewCreateInfo(*pCreateInfo);
-        // In order to create a valid buffer view, the buffer must have been created with at least one of the
-        // following flags:  UNIFORM_TEXEL_BUFFER_BIT or STORAGE_TEXEL_BUFFER_BIT
-        validate_buffer_usage_flags(dev_data, pCreateInfo->buffer,
-                                    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, false,
-                                    "vkCreateBufferView()", "VK_BUFFER_USAGE_[STORAGE|UNIFORM]_TEXEL_BUFFER_BIT");
+        lock.lock();
+        dev_data->bufferViewMap[*pView] = unique_ptr<VkBufferViewCreateInfo>(new VkBufferViewCreateInfo(*pCreateInfo));
+        lock.unlock();
     }
     return result;
 }
@@ -5462,7 +5850,7 @@
         IMAGE_LAYOUT_NODE image_node;
         image_node.layout = pCreateInfo->initialLayout;
         image_node.format = pCreateInfo->format;
-        dev_data->imageMap.insert(std::make_pair(*pImage, IMAGE_NODE(pCreateInfo)));
+        dev_data->imageMap.insert(std::make_pair(*pImage, unique_ptr<IMAGE_NODE>(new IMAGE_NODE(*pImage, pCreateInfo))));
         ImageSubresourcePair subpair = {*pImage, false, VkImageSubresource()};
         dev_data->imageSubresourceMap[*pImage].push_back(subpair);
         dev_data->imageLayoutMap[subpair] = image_node;
@@ -5473,18 +5861,18 @@
 static void ResolveRemainingLevelsLayers(layer_data *dev_data, VkImageSubresourceRange *range, VkImage image) {
     /* expects global_lock to be held by caller */
 
-    auto image_node_it = dev_data->imageMap.find(image);
-    if (image_node_it != dev_data->imageMap.end()) {
+    auto image_node = getImageNode(dev_data, image);
+    if (image_node) {
         /* If the caller used the special values VK_REMAINING_MIP_LEVELS and
          * VK_REMAINING_ARRAY_LAYERS, resolve them now in our internal state to
          * the actual values.
          */
         if (range->levelCount == VK_REMAINING_MIP_LEVELS) {
-            range->levelCount = image_node_it->second.createInfo.mipLevels - range->baseMipLevel;
+            range->levelCount = image_node->createInfo.mipLevels - range->baseMipLevel;
         }
 
         if (range->layerCount == VK_REMAINING_ARRAY_LAYERS) {
-            range->layerCount = image_node_it->second.createInfo.arrayLayers - range->baseArrayLayer;
+            range->layerCount = image_node->createInfo.arrayLayers - range->baseArrayLayer;
         }
     }
 }
@@ -5497,40 +5885,49 @@
 
     *levels = range.levelCount;
     *layers = range.layerCount;
-    auto image_node_it = dev_data->imageMap.find(image);
-    if (image_node_it != dev_data->imageMap.end()) {
+    auto image_node = getImageNode(dev_data, image);
+    if (image_node) {
         if (range.levelCount == VK_REMAINING_MIP_LEVELS) {
-            *levels = image_node_it->second.createInfo.mipLevels - range.baseMipLevel;
+            *levels = image_node->createInfo.mipLevels - range.baseMipLevel;
         }
         if (range.layerCount == VK_REMAINING_ARRAY_LAYERS) {
-            *layers = image_node_it->second.createInfo.arrayLayers - range.baseArrayLayer;
+            *layers = image_node->createInfo.arrayLayers - range.baseArrayLayer;
         }
     }
 }
 
+static bool PreCallValidateCreateImageView(layer_data *dev_data, const VkImageViewCreateInfo *pCreateInfo) {
+    bool skip_call = false;
+    IMAGE_NODE *image_node = getImageNode(dev_data, pCreateInfo->image);
+    if (image_node) {
+        skip_call |= ValidateImageUsageFlags(dev_data, image_node,
+                                             VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
+                                                 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+                                             false, "vkCreateImageView()", "VK_IMAGE_USAGE_[SAMPLED|STORAGE|COLOR_ATTACHMENT]_BIT");
+        // If this isn't a sparse image, it needs to have memory backing it at CreateImageView time
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, image_node, "vkCreateImageView()");
+    }
+    return skip_call;
+}
+
+static inline void PostCallRecordCreateImageView(layer_data *dev_data, const VkImageViewCreateInfo *pCreateInfo, VkImageView *pView) {
+    dev_data->imageViewMap[*pView] = unique_ptr<VkImageViewCreateInfo>(new VkImageViewCreateInfo(*pCreateInfo));
+    ResolveRemainingLevelsLayers(dev_data, &dev_data->imageViewMap[*pView].get()->subresourceRange, pCreateInfo->image);
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL CreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
                                                const VkAllocationCallbacks *pAllocator, VkImageView *pView) {
-    bool skipCall = false;
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    {
-        // Validate that img has correct usage flags set
-        std::lock_guard<std::mutex> lock(global_lock);
-        skipCall |= validate_image_usage_flags(dev_data, pCreateInfo->image,
-                VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
-                VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
-                false, "vkCreateImageView()", "VK_IMAGE_USAGE_[SAMPLED|STORAGE|COLOR_ATTACHMENT]_BIT");
-    }
-
-    if (!skipCall) {
-        result = dev_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
-    }
-
+    std::unique_lock<std::mutex> lock(global_lock);
+    bool skip_call = PreCallValidateCreateImageView(dev_data, pCreateInfo);
+    lock.unlock();
+    if (skip_call)
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    VkResult result = dev_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
     if (VK_SUCCESS == result) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        VkImageViewCreateInfo localCI = VkImageViewCreateInfo(*pCreateInfo);
-        ResolveRemainingLevelsLayers(dev_data, &localCI.subresourceRange, pCreateInfo->image);
-        dev_data->imageViewMap[*pView] = localCI;
+        lock.lock();
+        PostCallRecordCreateImageView(dev_data, pCreateInfo, pView);
+        lock.unlock();
     }
 
     return result;
@@ -5543,13 +5940,9 @@
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
         auto &fence_node = dev_data->fenceMap[*pFence];
+        fence_node.fence = *pFence;
         fence_node.createInfo = *pCreateInfo;
-        fence_node.needsSignaled = true;
-        if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) {
-            fence_node.firstTimeFlag = true;
-            fence_node.needsSignaled = false;
-        }
-        fence_node.in_use.store(0);
+        fence_node.state = (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) ? FENCE_RETIRED : FENCE_UNSIGNALED;
     }
     return result;
 }
@@ -5613,7 +6006,7 @@
     //  1. Pipeline create state is first shadowed into PIPELINE_NODE struct
     //  2. Create state is then validated (which uses flags setup during shadowing)
     //  3. If everything looks good, we'll then create the pipeline and add NODE to pipelineMap
-    bool skipCall = false;
+    bool skip_call = false;
     // TODO : Improve this data struct w/ unique_ptrs so cleanup below is automatic
     vector<PIPELINE_NODE *> pPipeNode(count);
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
@@ -5624,13 +6017,13 @@
     for (i = 0; i < count; i++) {
         pPipeNode[i] = new PIPELINE_NODE;
         pPipeNode[i]->initGraphicsPipeline(&pCreateInfos[i]);
-        pPipeNode[i]->renderPass = getRenderPass(dev_data, pCreateInfos[i].renderPass);
-        pPipeNode[i]->pipelineLayout = getPipelineLayout(dev_data, pCreateInfos[i].layout);
+        pPipeNode[i]->render_pass_ci.initialize(getRenderPass(dev_data, pCreateInfos[i].renderPass)->pCreateInfo);
+        pPipeNode[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
 
-        skipCall |= verifyPipelineCreateState(dev_data, device, pPipeNode, i);
+        skip_call |= verifyPipelineCreateState(dev_data, device, pPipeNode, i);
     }
 
-    if (!skipCall) {
+    if (!skip_call) {
         lock.unlock();
         result = dev_data->device_dispatch_table->CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
                                                                           pPipelines);
@@ -5655,7 +6048,7 @@
                        const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
                        VkPipeline *pPipelines) {
     VkResult result = VK_SUCCESS;
-    bool skipCall = false;
+    bool skip_call = false;
 
     // TODO : Improve this data struct w/ unique_ptrs so cleanup below is automatic
     vector<PIPELINE_NODE *> pPipeNode(count);
@@ -5669,14 +6062,16 @@
         // Create and initialize internal tracking data structure
         pPipeNode[i] = new PIPELINE_NODE;
         pPipeNode[i]->initComputePipeline(&pCreateInfos[i]);
-        pPipeNode[i]->pipelineLayout = getPipelineLayout(dev_data, pCreateInfos[i].layout);
+        pPipeNode[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
         // memcpy(&pPipeNode[i]->computePipelineCI, (const void *)&pCreateInfos[i], sizeof(VkComputePipelineCreateInfo));
 
         // TODO: Add Compute Pipeline Verification
-        // skipCall |= verifyPipelineCreateState(dev_data, device, pPipeNode[i]);
+        skip_call |= !validate_compute_pipeline(dev_data->report_data, pPipeNode[i], &dev_data->phys_dev_properties.features,
+                                                dev_data->shaderModuleMap);
+        // skip_call |= verifyPipelineCreateState(dev_data, device, pPipeNode[i]);
     }
 
-    if (!skipCall) {
+    if (!skip_call) {
         lock.unlock();
         result = dev_data->device_dispatch_table->CreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
                                                                          pPipelines);
@@ -5727,82 +6122,82 @@
 static bool validatePushConstantRange(const layer_data *dev_data, const uint32_t offset, const uint32_t size,
                                       const char *caller_name, uint32_t index = 0) {
     uint32_t const maxPushConstantsSize = dev_data->phys_dev_properties.properties.limits.maxPushConstantsSize;
-    bool skipCall = false;
+    bool skip_call = false;
     // Check that offset + size don't exceed the max.
     // Prevent arithetic overflow here by avoiding addition and testing in this order.
     if ((offset >= maxPushConstantsSize) || (size > maxPushConstantsSize - offset)) {
         // This is a pain just to adapt the log message to the caller, but better to sort it out only when there is a problem.
         if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants index %u with offset %u and size %u that "
                                                               "exceeds this device's maxPushConstantSize of %u.",
                         caller_name, index, offset, size, maxPushConstantsSize);
         } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants with offset %u and size %u that "
-                                                                      "exceeds this device's maxPushConstantSize of %u.",
-                                caller_name, offset, size, maxPushConstantsSize);
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants with offset %u and size %u that "
+                                                                       "exceeds this device's maxPushConstantSize of %u.",
+                                 caller_name, offset, size, maxPushConstantsSize);
         } else {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name);
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name);
         }
     }
     // size needs to be non-zero and a multiple of 4.
     if ((size == 0) || ((size & 0x3) != 0)) {
         if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants index %u with "
                                                               "size %u. Size must be greater than zero and a multiple of 4.",
                         caller_name, index, size);
         } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants with "
                                                               "size %u. Size must be greater than zero and a multiple of 4.",
                         caller_name, size);
         } else {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name);
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name);
         }
     }
     // offset needs to be a multiple of 4.
     if ((offset & 0x3) != 0) {
         if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants index %u with "
-                                                                      "offset %u. Offset must be a multiple of 4.",
-                                caller_name, index, offset);
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants index %u with "
+                                                                       "offset %u. Offset must be a multiple of 4.",
+                                 caller_name, index, offset);
         } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants with "
-                                                                      "offset %u. Offset must be a multiple of 4.",
-                                caller_name, offset);
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants with "
+                                                                       "offset %u. Offset must be a multiple of 4.",
+                                 caller_name, offset);
         } else {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name);
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name);
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
                                                     const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     // Push Constant Range checks
     uint32_t i = 0;
     for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
-        skipCall |= validatePushConstantRange(dev_data, pCreateInfo->pPushConstantRanges[i].offset,
-                                              pCreateInfo->pPushConstantRanges[i].size, "vkCreatePipelineLayout()", i);
+        skip_call |= validatePushConstantRange(dev_data, pCreateInfo->pPushConstantRanges[i].offset,
+                                               pCreateInfo->pPushConstantRanges[i].size, "vkCreatePipelineLayout()", i);
         if (0 == pCreateInfo->pPushConstantRanges[i].stageFlags) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCreatePipelineLayout() call has no stageFlags set.");
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCreatePipelineLayout() call has no stageFlags set.");
         }
     }
     // Each range has been validated.  Now check for overlap between ranges (if they are good).
-    if (!skipCall) {
+    if (!skip_call) {
         uint32_t i, j;
         for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
             for (j = i + 1; j < pCreateInfo->pushConstantRangeCount; ++j) {
@@ -5811,7 +6206,7 @@
                 const uint32_t minB = pCreateInfo->pPushConstantRanges[j].offset;
                 const uint32_t maxB = minB + pCreateInfo->pPushConstantRanges[j].size;
                 if ((minA <= minB && maxA > minB) || (minB <= minA && maxB > minA)) {
-                    skipCall |=
+                    skip_call |=
                         log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                                 DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCreatePipelineLayout() call has push constants with "
                                                                       "overlapping ranges: %u:[%u, %u), %u:[%u, %u)",
@@ -5821,22 +6216,21 @@
         }
     }
 
-    if (skipCall)
+    if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
     VkResult result = dev_data->device_dispatch_table->CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
         PIPELINE_LAYOUT_NODE &plNode = dev_data->pipelineLayoutMap[*pPipelineLayout];
-        plNode.descriptorSetLayouts.resize(pCreateInfo->setLayoutCount);
-        plNode.setLayouts.resize(pCreateInfo->setLayoutCount);
+        plNode.layout = *pPipelineLayout;
+        plNode.set_layouts.resize(pCreateInfo->setLayoutCount);
         for (i = 0; i < pCreateInfo->setLayoutCount; ++i) {
-            plNode.descriptorSetLayouts[i] = pCreateInfo->pSetLayouts[i];
-            plNode.setLayouts[i] = getDescriptorSetLayout(dev_data, pCreateInfo->pSetLayouts[i]);
+            plNode.set_layouts[i] = getDescriptorSetLayout(dev_data, pCreateInfo->pSetLayouts[i]);
         }
-        plNode.pushConstantRanges.resize(pCreateInfo->pushConstantRangeCount);
+        plNode.push_constant_ranges.resize(pCreateInfo->pushConstantRangeCount);
         for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
-            plNode.pushConstantRanges[i] = pCreateInfo->pPushConstantRanges[i];
+            plNode.push_constant_ranges[i] = pCreateInfo->pPushConstantRanges[i];
         }
     }
     return result;
@@ -5879,160 +6273,98 @@
     }
     return result;
 }
-
 // Ensure the pool contains enough descriptors and descriptor sets to satisfy
-// an allocation request. Fills requiredDescriptorsByType with the total number
-// of descriptors of each type required, for later update.
-static bool PreCallValidateAllocateDescriptorSets(layer_data *dev_data, DESCRIPTOR_POOL_NODE *pPoolNode, uint32_t count,
-                                                  std::vector<cvdescriptorset::DescriptorSetLayout const *> const & layout_nodes,
-                                                  uint32_t requiredDescriptorsByType[]) {
-    bool skipCall = false;
-
-    // Track number of descriptorSets allowable in this pool
-    if (pPoolNode->availableSets < count) {
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-                            reinterpret_cast<uint64_t &>(pPoolNode->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS",
-                            "Unable to allocate %u descriptorSets from pool 0x%" PRIxLEAST64
-                            ". This pool only has %d descriptorSets remaining.",
-                            count, reinterpret_cast<uint64_t &>(pPoolNode->pool), pPoolNode->availableSets);
-    }
-
-    // Count total descriptors required per type
-    for (auto layout_node : layout_nodes) {
-        if (layout_node) {
-            for (uint32_t j = 0; j < layout_node->GetBindingCount(); ++j) {
-                const auto &binding_layout = layout_node->GetDescriptorSetLayoutBindingPtrFromIndex(j);
-                uint32_t typeIndex = static_cast<uint32_t>(binding_layout->descriptorType);
-                requiredDescriptorsByType[typeIndex] += binding_layout->descriptorCount;
-            }
-        }
-    }
-
-    // Determine whether descriptor counts are satisfiable
-    for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
-        if (requiredDescriptorsByType[i] > pPoolNode->availableDescriptorTypeCount[i]) {
-            skipCall |= log_msg(
-                    dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-                    reinterpret_cast<const uint64_t &>(pPoolNode->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS",
-                    "Unable to allocate %u descriptors of type %s from pool 0x%" PRIxLEAST64
-                    ". This pool only has %d descriptors of this type remaining.",
-                    requiredDescriptorsByType[i], string_VkDescriptorType(VkDescriptorType(i)), (uint64_t)pPoolNode->pool,
-                    pPoolNode->availableDescriptorTypeCount[i]);
-        }
-    }
-
-    return skipCall;
+// an allocation request. Fills common_data with the total number of descriptors of each type required,
+// as well as DescriptorSetLayout ptrs used for later update.
+static bool PreCallValidateAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo,
+                                                  cvdescriptorset::AllocateDescriptorSetsData *common_data) {
+    // All state checks for AllocateDescriptorSets is done in single function
+    return cvdescriptorset::ValidateAllocateDescriptorSets(dev_data->report_data, pAllocateInfo, dev_data, common_data);
+}
+// Allocation state was good and call down chain was made so update state based on allocating descriptor sets
+static void PostCallRecordAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo,
+                                                 VkDescriptorSet *pDescriptorSets,
+                                                 const cvdescriptorset::AllocateDescriptorSetsData *common_data) {
+    // All the updates are contained in a single cvdescriptorset function
+    cvdescriptorset::PerformAllocateDescriptorSets(pAllocateInfo, pDescriptorSets, common_data, &dev_data->descriptorPoolMap,
+                                                   &dev_data->setMap, dev_data);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
 AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets) {
-    bool skipCall = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-
-    uint32_t requiredDescriptorsByType[VK_DESCRIPTOR_TYPE_RANGE_SIZE] {};
-    std::vector<cvdescriptorset::DescriptorSetLayout const *> layout_nodes(pAllocateInfo->descriptorSetCount, nullptr);
-
     std::unique_lock<std::mutex> lock(global_lock);
-
-    for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
-        layout_nodes[i] = getDescriptorSetLayout(dev_data, pAllocateInfo->pSetLayouts[i]);
-        if (!layout_nodes[i]) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT,
-                        (uint64_t)pAllocateInfo->pSetLayouts[i], __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS",
-                        "Unable to find set layout node for layout 0x%" PRIxLEAST64 " specified in vkAllocateDescriptorSets() call",
-                        (uint64_t)pAllocateInfo->pSetLayouts[i]);
-        }
-    }
-
-    DESCRIPTOR_POOL_NODE *pPoolNode = getPoolNode(dev_data, pAllocateInfo->descriptorPool);
-
-    if (!pPoolNode) {
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-                            (uint64_t)pAllocateInfo->descriptorPool, __LINE__, DRAWSTATE_INVALID_POOL, "DS",
-                            "Unable to find pool node for pool 0x%" PRIxLEAST64 " specified in vkAllocateDescriptorSets() call",
-                            (uint64_t)pAllocateInfo->descriptorPool);
-    } else { // Make sure pool has all the available descriptors before calling down chain
-        skipCall |= PreCallValidateAllocateDescriptorSets(dev_data, pPoolNode, pAllocateInfo->descriptorSetCount,
-                                                          layout_nodes, requiredDescriptorsByType);
-    }
+    cvdescriptorset::AllocateDescriptorSetsData common_data(pAllocateInfo->descriptorSetCount);
+    bool skip_call = PreCallValidateAllocateDescriptorSets(dev_data, pAllocateInfo, &common_data);
     lock.unlock();
 
-    if (skipCall)
+    if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
     VkResult result = dev_data->device_dispatch_table->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
 
     if (VK_SUCCESS == result) {
         lock.lock();
-        if (pPoolNode) {
-            /* Account for sets and descriptors allocated */
-            pPoolNode->availableSets -= pAllocateInfo->descriptorSetCount;
-            for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
-                pPoolNode->availableDescriptorTypeCount[i] -= requiredDescriptorsByType[i];
-            }
-
-            /* Create tracking object for each descriptor set; insert into
-             * global map and the pool's set.
-             */
-            for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
-                if (layout_nodes[i]) {
-                    auto pNewNode = new cvdescriptorset::DescriptorSet(
-                            pDescriptorSets[i], layout_nodes[i], &dev_data->bufferMap, &dev_data->memObjMap, &dev_data->bufferViewMap,
-                            &dev_data->samplerMap, &dev_data->imageViewMap, &dev_data->imageMap,
-                            &dev_data->device_extensions.imageToSwapchainMap, &dev_data->device_extensions.swapchainMap);
-
-                    pPoolNode->sets.insert(pNewNode);
-                    pNewNode->in_use.store(0);
-                    dev_data->setMap[pDescriptorSets[i]] = pNewNode;
-                }
-            }
-        }
+        PostCallRecordAllocateDescriptorSets(dev_data, pAllocateInfo, pDescriptorSets, &common_data);
         lock.unlock();
     }
     return result;
 }
+// Verify state before freeing DescriptorSets
+static bool PreCallValidateFreeDescriptorSets(const layer_data *dev_data, VkDescriptorPool pool, uint32_t count,
+                                              const VkDescriptorSet *descriptor_sets) {
+    bool skip_call = false;
+    // First make sure sets being destroyed are not currently in-use
+    for (uint32_t i = 0; i < count; ++i)
+        skip_call |= validateIdleDescriptorSet(dev_data, descriptor_sets[i], "vkFreeDescriptorSets");
+
+    DESCRIPTOR_POOL_NODE *pool_node = getPoolNode(dev_data, pool);
+    if (pool_node && !(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT & pool_node->createInfo.flags)) {
+        // Can't Free from a NON_FREE pool
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
+                             reinterpret_cast<uint64_t &>(pool), __LINE__, DRAWSTATE_CANT_FREE_FROM_NON_FREE_POOL, "DS",
+                             "It is invalid to call vkFreeDescriptorSets() with a pool created without setting "
+                             "VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.");
+    }
+    return skip_call;
+}
+// Sets have been removed from the pool so update underlying state
+static void PostCallRecordFreeDescriptorSets(layer_data *dev_data, VkDescriptorPool pool, uint32_t count,
+                                             const VkDescriptorSet *descriptor_sets) {
+    DESCRIPTOR_POOL_NODE *pool_state = getPoolNode(dev_data, pool);
+    // Update available descriptor sets in pool
+    pool_state->availableSets += count;
+
+    // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap
+    for (uint32_t i = 0; i < count; ++i) {
+        auto set_state = dev_data->setMap[descriptor_sets[i]];
+        uint32_t type_index = 0, descriptor_count = 0;
+        for (uint32_t j = 0; j < set_state->GetBindingCount(); ++j) {
+            type_index = static_cast<uint32_t>(set_state->GetTypeFromIndex(j));
+            descriptor_count = set_state->GetDescriptorCountFromIndex(j);
+            pool_state->availableDescriptorTypeCount[type_index] += descriptor_count;
+        }
+        freeDescriptorSet(dev_data, set_state);
+        pool_state->sets.erase(set_state);
+    }
+}
 
 VKAPI_ATTR VkResult VKAPI_CALL
 FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet *pDescriptorSets) {
-    bool skipCall = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     // Make sure that no sets being destroyed are in-flight
     std::unique_lock<std::mutex> lock(global_lock);
-    for (uint32_t i = 0; i < count; ++i)
-        skipCall |= validateIdleDescriptorSet(dev_data, pDescriptorSets[i], "vkFreeDescriptorSets");
-    DESCRIPTOR_POOL_NODE *pPoolNode = getPoolNode(dev_data, descriptorPool);
-    if (pPoolNode && !(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT & pPoolNode->createInfo.flags)) {
-        // Can't Free from a NON_FREE pool
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
-                            (uint64_t)device, __LINE__, DRAWSTATE_CANT_FREE_FROM_NON_FREE_POOL, "DS",
-                            "It is invalid to call vkFreeDescriptorSets() with a pool created without setting "
-                            "VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.");
-    }
+    bool skip_call = PreCallValidateFreeDescriptorSets(dev_data, descriptorPool, count, pDescriptorSets);
     lock.unlock();
-    if (skipCall)
+
+    if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
     VkResult result = dev_data->device_dispatch_table->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
     if (VK_SUCCESS == result) {
         lock.lock();
-
-        // Update available descriptor sets in pool
-        pPoolNode->availableSets += count;
-
-        // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap
-        for (uint32_t i = 0; i < count; ++i) {
-            cvdescriptorset::DescriptorSet *pSet = dev_data->setMap[pDescriptorSets[i]]; // getSetNode() without locking
-            uint32_t typeIndex = 0, poolSizeCount = 0;
-            for (uint32_t j = 0; j < pSet->GetBindingCount(); ++j) {
-                typeIndex = static_cast<uint32_t>(pSet->GetTypeFromIndex(j));
-                poolSizeCount = pSet->GetDescriptorCountFromIndex(j);
-                pPoolNode->availableDescriptorTypeCount[typeIndex] += poolSizeCount;
-            }
-            freeDescriptorSet(dev_data, pSet);
-            pPoolNode->sets.erase(pSet);
-        }
+        PostCallRecordFreeDescriptorSets(dev_data, descriptorPool, count, pDescriptorSets);
         lock.unlock();
     }
-    // TODO : Any other clean-up or book-keeping to do here?
     return result;
 }
 // TODO : This is a Proof-of-concept for core validation architecture
@@ -6049,14 +6381,14 @@
     // Now make call(s) that validate state, but don't perform state updates in this function
     // Note, here DescriptorSets is unique in that we don't yet have an instance. Using a helper function in the
     //  namespace which will parse params and make calls into specific class instances
-    return cvdescriptorset::ValidateUpdateDescriptorSets(dev_data->report_data, dev_data->setMap, descriptorWriteCount,
-                                                         pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
+    return cvdescriptorset::ValidateUpdateDescriptorSets(dev_data->report_data, dev_data, descriptorWriteCount, pDescriptorWrites,
+                                                         descriptorCopyCount, pDescriptorCopies);
 }
 // PostCallRecord* handles recording state updates following call down chain to UpdateDescriptorSets()
 static void PostCallRecordUpdateDescriptorSets(layer_data *dev_data, uint32_t descriptorWriteCount,
                                                const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount,
                                                const VkCopyDescriptorSet *pDescriptorCopies) {
-    cvdescriptorset::PerformUpdateDescriptorSets(dev_data->setMap, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
+    cvdescriptorset::PerformUpdateDescriptorSets(dev_data, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
                                                  pDescriptorCopies);
 }
 
@@ -6085,11 +6417,12 @@
     VkResult result = dev_data->device_dispatch_table->AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer);
     if (VK_SUCCESS == result) {
         std::unique_lock<std::mutex> lock(global_lock);
-        auto const &cp_it = dev_data->commandPoolMap.find(pCreateInfo->commandPool);
-        if (cp_it != dev_data->commandPoolMap.end()) {
+        auto pPool = getCommandPoolNode(dev_data, pCreateInfo->commandPool);
+
+        if (pPool) {
             for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) {
                 // Add command buffer to its commandPool map
-                cp_it->second.commandBuffers.push_back(pCommandBuffer[i]);
+                pPool->commandBuffers.push_back(pCommandBuffer[i]);
                 GLOBAL_CB_NODE *pCB = new GLOBAL_CB_NODE;
                 // Add command buffer to map
                 dev_data->commandBufferMap[pCommandBuffer[i]] = pCB;
@@ -6106,7 +6439,7 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL
 BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     // Validate command buffer level
@@ -6114,7 +6447,7 @@
     if (pCB) {
         // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
         if (dev_data->globalInFlightCmdBuffers.count(commandBuffer)) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)commandBuffer, __LINE__, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM",
                         "Calling vkBeginCommandBuffer() on active CB 0x%p before it has completed. "
@@ -6126,7 +6459,7 @@
             // Secondary Command Buffer
             const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
             if (!pInfo) {
-                skipCall |=
+                skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
                             "vkBeginCommandBuffer(): Secondary Command Buffer (0x%p) must have inheritance info.",
@@ -6134,69 +6467,72 @@
             } else {
                 if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
                     if (!pInfo->renderPass) { // renderpass should NOT be null for a Secondary CB
-                        skipCall |= log_msg(
+                        skip_call |= log_msg(
                             dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
                             "vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) must specify a valid renderpass parameter.",
                             reinterpret_cast<void *>(commandBuffer));
                     }
                     if (!pInfo->framebuffer) { // framebuffer may be null for a Secondary CB, but this affects perf
-                        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                                            VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                                            reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE,
-                                            "DS", "vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) may perform better if a "
-                                                  "valid framebuffer parameter is specified.",
-                                            reinterpret_cast<void *>(commandBuffer));
+                        skip_call |= log_msg(
+                            dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                            reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
+                            "vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) may perform better if a "
+                            "valid framebuffer parameter is specified.",
+                            reinterpret_cast<void *>(commandBuffer));
                     } else {
                         string errorString = "";
                         auto framebuffer = getFramebuffer(dev_data, pInfo->framebuffer);
                         if (framebuffer) {
-                            VkRenderPass fbRP = framebuffer->createInfo.renderPass;
-                            if (!verify_renderpass_compatibility(dev_data, fbRP, pInfo->renderPass, errorString)) {
+                            if ((framebuffer->createInfo.renderPass != pInfo->renderPass) &&
+                                !verify_renderpass_compatibility(dev_data, framebuffer->renderPassCreateInfo.ptr(),
+                                                                 getRenderPass(dev_data, pInfo->renderPass)->pCreateInfo,
+                                                                 errorString)) {
                                 // renderPass that framebuffer was created with must be compatible with local renderPass
-                                skipCall |=
-                                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                            VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                                            reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE,
-                                            "DS", "vkBeginCommandBuffer(): Secondary Command "
-                                                  "Buffer (0x%p) renderPass (0x%" PRIxLEAST64 ") is incompatible w/ framebuffer "
-                                                  "(0x%" PRIxLEAST64 ") w/ render pass (0x%" PRIxLEAST64 ") due to: %s",
-                                            reinterpret_cast<void *>(commandBuffer), (uint64_t)(pInfo->renderPass),
-                                            (uint64_t)(pInfo->framebuffer), (uint64_t)(fbRP), errorString.c_str());
+                                skip_call |= log_msg(
+                                    dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t>(commandBuffer),
+                                    __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
+                                    "vkBeginCommandBuffer(): Secondary Command "
+                                    "Buffer (0x%p) renderPass (0x%" PRIxLEAST64 ") is incompatible w/ framebuffer "
+                                    "(0x%" PRIxLEAST64 ") w/ render pass (0x%" PRIxLEAST64 ") due to: %s",
+                                    reinterpret_cast<void *>(commandBuffer), reinterpret_cast<const uint64_t &>(pInfo->renderPass),
+                                    reinterpret_cast<const uint64_t &>(pInfo->framebuffer),
+                                    reinterpret_cast<uint64_t &>(framebuffer->createInfo.renderPass), errorString.c_str());
                             }
                             // Connect this framebuffer to this cmdBuffer
-                            framebuffer->referencingCmdBuffers.insert(pCB->commandBuffer);
+                            framebuffer->cb_bindings.insert(pCB);
                         }
                     }
                 }
                 if ((pInfo->occlusionQueryEnable == VK_FALSE ||
                      dev_data->phys_dev_properties.features.occlusionQueryPrecise == VK_FALSE) &&
                     (pInfo->queryFlags & VK_QUERY_CONTROL_PRECISE_BIT)) {
-                    skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                        VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t>(commandBuffer),
-                                        __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
-                                        "vkBeginCommandBuffer(): Secondary Command Buffer (0x%p) must not have "
-                                        "VK_QUERY_CONTROL_PRECISE_BIT if occulusionQuery is disabled or the device does not "
-                                        "support precise occlusion queries.",
-                                        reinterpret_cast<void *>(commandBuffer));
+                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t>(commandBuffer),
+                                         __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
+                                         "vkBeginCommandBuffer(): Secondary Command Buffer (0x%p) must not have "
+                                         "VK_QUERY_CONTROL_PRECISE_BIT if occulusionQuery is disabled or the device does not "
+                                         "support precise occlusion queries.",
+                                         reinterpret_cast<void *>(commandBuffer));
                 }
             }
             if (pInfo && pInfo->renderPass != VK_NULL_HANDLE) {
                 auto renderPass = getRenderPass(dev_data, pInfo->renderPass);
                 if (renderPass) {
                     if (pInfo->subpass >= renderPass->pCreateInfo->subpassCount) {
-                        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                            VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
-                                            DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
-                                            "vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) must has a subpass index (%d) "
-                                            "that is less than the number of subpasses (%d).",
-                                            (void *)commandBuffer, pInfo->subpass, renderPass->pCreateInfo->subpassCount);
+                        skip_call |= log_msg(
+                            dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                            (uint64_t)commandBuffer, __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
+                            "vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) must has a subpass index (%d) "
+                            "that is less than the number of subpasses (%d).",
+                            (void *)commandBuffer, pInfo->subpass, renderPass->pCreateInfo->subpassCount);
                     }
                 }
             }
         }
         if (CB_RECORDING == pCB->state) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)commandBuffer, __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
                         "vkBeginCommandBuffer(): Cannot call Begin on CB (0x%" PRIxLEAST64
@@ -6204,8 +6540,9 @@
                         (uint64_t)commandBuffer);
         } else if (CB_RECORDED == pCB->state || (CB_INVALID == pCB->state && CMD_END == pCB->cmds.back().type)) {
             VkCommandPool cmdPool = pCB->createInfo.commandPool;
-            if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & dev_data->commandPoolMap[cmdPool].createFlags)) {
-                skipCall |=
+            auto pPool = getCommandPoolNode(dev_data, cmdPool);
+            if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & pPool->createFlags)) {
+                skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, "DS",
                             "Call to vkBeginCommandBuffer() on command buffer (0x%" PRIxLEAST64
@@ -6230,12 +6567,12 @@
             }
         }
     } else {
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
-                            "In vkBeginCommandBuffer() and unable to find CommandBuffer Node for CB 0x%p!", (void *)commandBuffer);
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                             (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
+                             "In vkBeginCommandBuffer() and unable to find CommandBuffer Node for CB 0x%p!", (void *)commandBuffer);
     }
     lock.unlock();
-    if (skipCall) {
+    if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
     }
     VkResult result = dev_data->device_dispatch_table->BeginCommandBuffer(commandBuffer, pBeginInfo);
@@ -6244,7 +6581,7 @@
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer) {
-    bool skipCall = false;
+    bool skip_call = false;
     VkResult result = VK_SUCCESS;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
@@ -6253,17 +6590,17 @@
         if ((VK_COMMAND_BUFFER_LEVEL_PRIMARY == pCB->createInfo.level) || !(pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
             // This needs spec clarification to update valid usage, see comments in PR:
             // https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/pull/516#discussion_r63013756
-            skipCall |= insideRenderPass(dev_data, pCB, "vkEndCommandBuffer");
+            skip_call |= insideRenderPass(dev_data, pCB, "vkEndCommandBuffer");
         }
-        skipCall |= addCmd(dev_data, pCB, CMD_END, "vkEndCommandBuffer()");
+        skip_call |= addCmd(dev_data, pCB, CMD_END, "vkEndCommandBuffer()");
         for (auto query : pCB->activeQueries) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INVALID_QUERY, "DS",
-                                "Ending command buffer with in progress query: queryPool 0x%" PRIx64 ", index %d",
-                                (uint64_t)(query.pool), query.index);
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_INVALID_QUERY, "DS",
+                                 "Ending command buffer with in progress query: queryPool 0x%" PRIx64 ", index %d",
+                                 (uint64_t)(query.pool), query.index);
         }
     }
-    if (!skipCall) {
+    if (!skip_call) {
         lock.unlock();
         result = dev_data->device_dispatch_table->EndCommandBuffer(commandBuffer);
         lock.lock();
@@ -6287,20 +6624,22 @@
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     VkCommandPool cmdPool = pCB->createInfo.commandPool;
-    if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & dev_data->commandPoolMap[cmdPool].createFlags)) {
+    auto pPool = getCommandPoolNode(dev_data, cmdPool);
+    if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & pPool->createFlags)) {
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                              (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, "DS",
                              "Attempt to reset command buffer (0x%" PRIxLEAST64 ") created from command pool (0x%" PRIxLEAST64
                              ") that does NOT have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set.",
                              (uint64_t)commandBuffer, (uint64_t)cmdPool);
     }
-    skip_call |= checkAndClearCommandBufferInFlight(dev_data, pCB, "reset");
+    skip_call |= checkCommandBufferInFlight(dev_data, pCB, "reset");
     lock.unlock();
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
     VkResult result = dev_data->device_dispatch_table->ResetCommandBuffer(commandBuffer, flags);
     if (VK_SUCCESS == result) {
         lock.lock();
+        dev_data->globalInFlightCmdBuffers.erase(commandBuffer);
         resetCB(dev_data, commandBuffer);
         lock.unlock();
     }
@@ -6309,14 +6648,14 @@
 
 VKAPI_ATTR void VKAPI_CALL
 CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_BINDPIPELINE, "vkCmdBindPipeline()");
+        skip_call |= addCmd(dev_data, pCB, CMD_BINDPIPELINE, "vkCmdBindPipeline()");
         if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && (pCB->activeRenderPass)) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
                         (uint64_t)pipeline, __LINE__, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
                         "Incorrectly binding compute pipeline (0x%" PRIxLEAST64 ") during active RenderPass (0x%" PRIxLEAST64 ")",
@@ -6329,47 +6668,47 @@
             set_cb_pso_status(pCB, pPN);
             set_pipeline_state(pPN);
         } else {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
-                                (uint64_t)pipeline, __LINE__, DRAWSTATE_INVALID_PIPELINE, "DS",
-                                "Attempt to bind Pipeline 0x%" PRIxLEAST64 " that doesn't exist!", (uint64_t)(pipeline));
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+                                 (uint64_t)pipeline, __LINE__, DRAWSTATE_INVALID_PIPELINE, "DS",
+                                 "Attempt to bind Pipeline 0x%" PRIxLEAST64 " that doesn't exist!", (uint64_t)(pipeline));
         }
+        addCommandBufferBinding(&getPipeline(dev_data, pipeline)->cb_bindings,
+                                {reinterpret_cast<uint64_t &>(pipeline), VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT}, pCB);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETVIEWPORTSTATE, "vkCmdSetViewport()");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETVIEWPORTSTATE, "vkCmdSetViewport()");
         pCB->status |= CBSTATUS_VIEWPORT_SET;
-        pCB->viewports.resize(viewportCount);
-        memcpy(pCB->viewports.data(), pViewports, viewportCount * sizeof(VkViewport));
+        pCB->viewportMask |= ((1u<<viewportCount) - 1u) << firstViewport;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETSCISSORSTATE, "vkCmdSetScissor()");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETSCISSORSTATE, "vkCmdSetScissor()");
         pCB->status |= CBSTATUS_SCISSOR_SET;
-        pCB->scissors.resize(scissorCount);
-        memcpy(pCB->scissors.data(), pScissors, scissorCount * sizeof(VkRect2D));
+        pCB->scissorMask |= ((1u<<scissorCount) - 1u) << firstScissor;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
 }
 
@@ -6399,91 +6738,91 @@
 
 VKAPI_ATTR void VKAPI_CALL
 CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETDEPTHBIASSTATE, "vkCmdSetDepthBias()");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETDEPTHBIASSTATE, "vkCmdSetDepthBias()");
         pCB->status |= CBSTATUS_DEPTH_BIAS_SET;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp,
                                                          depthBiasSlopeFactor);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETBLENDSTATE, "vkCmdSetBlendConstants()");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETBLENDSTATE, "vkCmdSetBlendConstants()");
         pCB->status |= CBSTATUS_BLEND_CONSTANTS_SET;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetBlendConstants(commandBuffer, blendConstants);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETDEPTHBOUNDSSTATE, "vkCmdSetDepthBounds()");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETDEPTHBOUNDSSTATE, "vkCmdSetDepthBounds()");
         pCB->status |= CBSTATUS_DEPTH_BOUNDS_SET;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETSTENCILREADMASKSTATE, "vkCmdSetStencilCompareMask()");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETSTENCILREADMASKSTATE, "vkCmdSetStencilCompareMask()");
         pCB->status |= CBSTATUS_STENCIL_READ_MASK_SET;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETSTENCILWRITEMASKSTATE, "vkCmdSetStencilWriteMask()");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETSTENCILWRITEMASKSTATE, "vkCmdSetStencilWriteMask()");
         pCB->status |= CBSTATUS_STENCIL_WRITE_MASK_SET;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETSTENCILREFERENCESTATE, "vkCmdSetStencilReference()");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETSTENCILREFERENCESTATE, "vkCmdSetStencilReference()");
         pCB->status |= CBSTATUS_STENCIL_REFERENCE_SET;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetStencilReference(commandBuffer, faceMask, reference);
 }
 
@@ -6491,7 +6830,7 @@
 CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
                       uint32_t firstSet, uint32_t setCount, const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
                       const uint32_t *pDynamicOffsets) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
@@ -6506,33 +6845,34 @@
                 pCB->lastBound[pipelineBindPoint].dynamicOffsets.resize(lastSetIndex + 1);
             }
             auto oldFinalBoundSet = pCB->lastBound[pipelineBindPoint].boundDescriptorSets[lastSetIndex];
+            auto pipeline_layout = getPipelineLayout(dev_data, layout);
             for (uint32_t i = 0; i < setCount; i++) {
                 cvdescriptorset::DescriptorSet *pSet = getSetNode(dev_data, pDescriptorSets[i]);
                 if (pSet) {
                     pCB->lastBound[pipelineBindPoint].uniqueBoundSets.insert(pSet);
                     pSet->BindCommandBuffer(pCB);
-                    pCB->lastBound[pipelineBindPoint].pipelineLayout = layout;
+                    pCB->lastBound[pipelineBindPoint].pipeline_layout = *pipeline_layout;
                     pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i + firstSet] = pSet;
-                    skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
-                                        VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
-                                        DRAWSTATE_NONE, "DS", "DS 0x%" PRIxLEAST64 " bound on pipeline %s",
-                                        (uint64_t)pDescriptorSets[i], string_VkPipelineBindPoint(pipelineBindPoint));
+                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
+                                         VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
+                                         DRAWSTATE_NONE, "DS", "DS 0x%" PRIxLEAST64 " bound on pipeline %s",
+                                         (uint64_t)pDescriptorSets[i], string_VkPipelineBindPoint(pipelineBindPoint));
                     if (!pSet->IsUpdated() && (pSet->GetTotalDescriptorCount() != 0)) {
-                        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                                            VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i],
-                                            __LINE__, DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
-                                            "DS 0x%" PRIxLEAST64
-                                            " bound but it was never updated. You may want to either update it or not bind it.",
-                                            (uint64_t)pDescriptorSets[i]);
+                        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                                             VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
+                                             DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
+                                             "DS 0x%" PRIxLEAST64
+                                             " bound but it was never updated. You may want to either update it or not bind it.",
+                                             (uint64_t)pDescriptorSets[i]);
                     }
                     // Verify that set being bound is compatible with overlapping setLayout of pipelineLayout
-                    if (!verify_set_layout_compatibility(dev_data, pSet, layout, i + firstSet, errorString)) {
-                        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                            VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
-                                            DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, "DS",
-                                            "descriptorSet #%u being bound is not compatible with overlapping descriptorSetLayout "
-                                            "at index %u of pipelineLayout 0x%" PRIxLEAST64 " due to: %s",
-                                            i, i + firstSet, reinterpret_cast<uint64_t &>(layout), errorString.c_str());
+                    if (!verify_set_layout_compatibility(dev_data, pSet, pipeline_layout, i + firstSet, errorString)) {
+                        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
+                                             DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, "DS",
+                                             "descriptorSet #%u being bound is not compatible with overlapping descriptorSetLayout "
+                                             "at index %u of pipelineLayout 0x%" PRIxLEAST64 " due to: %s",
+                                             i, i + firstSet, reinterpret_cast<uint64_t &>(layout), errorString.c_str());
                     }
 
                     auto setDynamicDescriptorCount = pSet->GetDynamicDescriptorCount();
@@ -6542,7 +6882,7 @@
                     if (setDynamicDescriptorCount) {
                         // First make sure we won't overstep bounds of pDynamicOffsets array
                         if ((totalDynamicDescriptors + setDynamicDescriptorCount) > dynamicOffsetCount) {
-                            skipCall |=
+                            skip_call |=
                                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                         VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
                                         DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, "DS",
@@ -6559,7 +6899,7 @@
                                     if (vk_safe_modulo(
                                             pDynamicOffsets[cur_dyn_offset],
                                             dev_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment) != 0) {
-                                        skipCall |= log_msg(
+                                        skip_call |= log_msg(
                                             dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                             VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
                                             DRAWSTATE_INVALID_UNIFORM_BUFFER_OFFSET, "DS",
@@ -6573,7 +6913,7 @@
                                     if (vk_safe_modulo(
                                             pDynamicOffsets[cur_dyn_offset],
                                             dev_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment) != 0) {
-                                        skipCall |= log_msg(
+                                        skip_call |= log_msg(
                                             dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                             VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
                                             DRAWSTATE_INVALID_STORAGE_BUFFER_OFFSET, "DS",
@@ -6595,19 +6935,19 @@
                         }
                     }
                 } else {
-                    skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                        VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
-                                        DRAWSTATE_INVALID_SET, "DS", "Attempt to bind DS 0x%" PRIxLEAST64 " that doesn't exist!",
-                                        (uint64_t)pDescriptorSets[i]);
+                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
+                                         DRAWSTATE_INVALID_SET, "DS", "Attempt to bind DS 0x%" PRIxLEAST64 " that doesn't exist!",
+                                         (uint64_t)pDescriptorSets[i]);
                 }
-                skipCall |= addCmd(dev_data, pCB, CMD_BINDDESCRIPTORSETS, "vkCmdBindDescriptorSets()");
+                skip_call |= addCmd(dev_data, pCB, CMD_BINDDESCRIPTORSETS, "vkCmdBindDescriptorSets()");
                 // For any previously bound sets, need to set them to "invalid" if they were disturbed by this update
                 if (firstSet > 0) { // Check set #s below the first bound set
                     for (uint32_t i = 0; i < firstSet; ++i) {
                         if (pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i] &&
                             !verify_set_layout_compatibility(dev_data, pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i],
-                                                             layout, i, errorString)) {
-                            skipCall |= log_msg(
+                                                             pipeline_layout, i, errorString)) {
+                            skip_call |= log_msg(
                                 dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                 VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                                 (uint64_t)pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i], __LINE__, DRAWSTATE_NONE, "DS",
@@ -6621,9 +6961,9 @@
                 // Check if newly last bound set invalidates any remaining bound sets
                 if ((pCB->lastBound[pipelineBindPoint].boundDescriptorSets.size() - 1) > (lastSetIndex)) {
                     if (oldFinalBoundSet &&
-                        !verify_set_layout_compatibility(dev_data, oldFinalBoundSet, layout, lastSetIndex, errorString)) {
+                        !verify_set_layout_compatibility(dev_data, oldFinalBoundSet, pipeline_layout, lastSetIndex, errorString)) {
                         auto old_set = oldFinalBoundSet->GetSet();
-                        skipCall |=
+                        skip_call |=
                             log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                     VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, reinterpret_cast<uint64_t &>(old_set), __LINE__,
                                     DRAWSTATE_NONE, "DS", "DescriptorSetDS 0x%" PRIxLEAST64
@@ -6639,37 +6979,39 @@
             }
             //  dynamicOffsetCount must equal the total number of dynamic descriptors in the sets being bound
             if (totalDynamicDescriptors != dynamicOffsetCount) {
-                skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
-                                    DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, "DS",
-                                    "Attempting to bind %u descriptorSets with %u dynamic descriptors, but dynamicOffsetCount "
-                                    "is %u. It should exactly match the number of dynamic descriptors.",
-                                    setCount, totalDynamicDescriptors, dynamicOffsetCount);
+                skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                            (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, "DS",
+                            "Attempting to bind %u descriptorSets with %u dynamic descriptors, but dynamicOffsetCount "
+                            "is %u. It should exactly match the number of dynamic descriptors.",
+                            setCount, totalDynamicDescriptors, dynamicOffsetCount);
             }
         } else {
-            skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdBindDescriptorSets()");
+            skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdBindDescriptorSets()");
         }
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, setCount,
                                                                pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     // TODO : Somewhere need to verify that IBs have correct usage state flagged
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory mem;
-    skipCall =
-        get_mem_binding_from_object(dev_data, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
-        std::function<bool()> function = [=]() { return validate_memory_is_valid(dev_data, mem, "vkCmdBindIndexBuffer()"); };
-        cb_data->second->validate_functions.push_back(function);
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_BINDINDEXBUFFER, "vkCmdBindIndexBuffer()");
+
+    auto buff_node = getBufferNode(dev_data, buffer);
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    if (cb_node && buff_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, buff_node, "vkCmdBindIndexBuffer()");
+        std::function<bool()> function = [=]() {
+            return validate_memory_is_valid(dev_data, buff_node->mem, "vkCmdBindIndexBuffer()");
+        };
+        cb_node->validate_functions.push_back(function);
+        skip_call |= addCmd(dev_data, cb_node, CMD_BINDINDEXBUFFER, "vkCmdBindIndexBuffer()");
         VkDeviceSize offset_align = 0;
         switch (indexType) {
         case VK_INDEX_TYPE_UINT16:
@@ -6683,15 +7025,17 @@
             break;
         }
         if (!offset_align || (offset % offset_align)) {
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, "DS",
-                                "vkCmdBindIndexBuffer() offset (0x%" PRIxLEAST64 ") does not fall on alignment (%s) boundary.",
-                                offset, string_VkIndexType(indexType));
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, "DS",
+                                 "vkCmdBindIndexBuffer() offset (0x%" PRIxLEAST64 ") does not fall on alignment (%s) boundary.",
+                                 offset, string_VkIndexType(indexType));
         }
-        cb_data->second->status |= CBSTATUS_INDEX_BUFFER_BOUND;
+        cb_node->status |= CBSTATUS_INDEX_BUFFER_BOUND;
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
 }
 
@@ -6710,26 +7054,29 @@
 VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
                                                 uint32_t bindingCount, const VkBuffer *pBuffers,
                                                 const VkDeviceSize *pOffsets) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     // TODO : Somewhere need to verify that VBs have correct usage state flagged
     std::unique_lock<std::mutex> lock(global_lock);
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
-        for (uint32_t i = 0; i < bindingCount; ++i) {
-            VkDeviceMemory mem;
-            skipCall |= get_mem_binding_from_object(dev_data, (uint64_t)pBuffers[i], VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
 
-            std::function<bool()> function = [=]() { return validate_memory_is_valid(dev_data, mem, "vkCmdBindVertexBuffers()"); };
-            cb_data->second->validate_functions.push_back(function);
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    if (cb_node) {
+        for (uint32_t i = 0; i < bindingCount; ++i) {
+            auto buff_node = getBufferNode(dev_data, pBuffers[i]);
+            assert(buff_node);
+            skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, buff_node, "vkCmdBindVertexBuffers()");
+            std::function<bool()> function = [=]() {
+                return validate_memory_is_valid(dev_data, buff_node->mem, "vkCmdBindVertexBuffers()");
+            };
+            cb_node->validate_functions.push_back(function);
         }
-        addCmd(dev_data, cb_data->second, CMD_BINDVERTEXBUFFER, "vkCmdBindVertexBuffer()");
-        updateResourceTracking(cb_data->second, firstBinding, bindingCount, pBuffers);
+        addCmd(dev_data, cb_node, CMD_BINDVERTEXBUFFER, "vkCmdBindVertexBuffer()");
+        updateResourceTracking(cb_node, firstBinding, bindingCount, pBuffers);
     } else {
-        skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdBindVertexBuffer()");
+        skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdBindVertexBuffer()");
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
 }
 
@@ -6738,25 +7085,23 @@
     bool skip_call = false;
 
     for (auto imageView : pCB->updateImages) {
-        auto iv_data = dev_data->imageViewMap.find(imageView);
-        if (iv_data == dev_data->imageViewMap.end())
+        auto iv_data = getImageViewData(dev_data, imageView);
+        if (!iv_data)
             continue;
-        VkImage image = iv_data->second.image;
-        VkDeviceMemory mem;
-        skip_call |=
-            get_mem_binding_from_object(dev_data, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
+
+        auto img_node = getImageNode(dev_data, iv_data->image);
+        assert(img_node);
         std::function<bool()> function = [=]() {
-            set_memory_valid(dev_data, mem, true, image);
+            set_memory_valid(dev_data, img_node->mem, true, iv_data->image);
             return false;
         };
         pCB->validate_functions.push_back(function);
     }
     for (auto buffer : pCB->updateBuffers) {
-        VkDeviceMemory mem;
-        skip_call |= get_mem_binding_from_object(dev_data, (uint64_t)buffer,
-                                                 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
+        auto buff_node = getBufferNode(dev_data, buffer);
+        assert(buff_node);
         std::function<bool()> function = [=]() {
-            set_memory_valid(dev_data, mem, true);
+            set_memory_valid(dev_data, buff_node->mem, true);
             return false;
         };
         pCB->validate_functions.push_back(function);
@@ -6766,27 +7111,27 @@
 
 VKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
                                    uint32_t firstVertex, uint32_t firstInstance) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_DRAW, "vkCmdDraw()");
+        skip_call |= addCmd(dev_data, pCB, CMD_DRAW, "vkCmdDraw()");
         pCB->drawCount[DRAW]++;
-        skipCall |= validate_and_update_draw_state(dev_data, pCB, false, VK_PIPELINE_BIND_POINT_GRAPHICS);
-        skipCall |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
+        skip_call |= validate_and_update_draw_state(dev_data, pCB, false, VK_PIPELINE_BIND_POINT_GRAPHICS);
+        skip_call |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
         // TODO : Need to pass commandBuffer as srcObj here
-        skipCall |=
+        skip_call |=
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
                     __LINE__, DRAWSTATE_NONE, "DS", "vkCmdDraw() call 0x%" PRIx64 ", reporting DS state:", g_drawCount[DRAW]++);
-        skipCall |= synchAndPrintDSConfig(dev_data, commandBuffer);
-        if (!skipCall) {
+        skip_call |= synchAndPrintDSConfig(dev_data, commandBuffer);
+        if (!skip_call) {
             updateResourceTrackingOnDraw(pCB);
         }
-        skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdDraw");
+        skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdDraw");
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
 }
 
@@ -6794,26 +7139,26 @@
                                           uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
                                                             uint32_t firstInstance) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-    bool skipCall = false;
+    bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_DRAWINDEXED, "vkCmdDrawIndexed()");
+        skip_call |= addCmd(dev_data, pCB, CMD_DRAWINDEXED, "vkCmdDrawIndexed()");
         pCB->drawCount[DRAW_INDEXED]++;
-        skipCall |= validate_and_update_draw_state(dev_data, pCB, true, VK_PIPELINE_BIND_POINT_GRAPHICS);
-        skipCall |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
+        skip_call |= validate_and_update_draw_state(dev_data, pCB, true, VK_PIPELINE_BIND_POINT_GRAPHICS);
+        skip_call |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
         // TODO : Need to pass commandBuffer as srcObj here
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_NONE, "DS",
-                            "vkCmdDrawIndexed() call 0x%" PRIx64 ", reporting DS state:", g_drawCount[DRAW_INDEXED]++);
-        skipCall |= synchAndPrintDSConfig(dev_data, commandBuffer);
-        if (!skipCall) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
+                             VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_NONE, "DS",
+                             "vkCmdDrawIndexed() call 0x%" PRIx64 ", reporting DS state:", g_drawCount[DRAW_INDEXED]++);
+        skip_call |= synchAndPrintDSConfig(dev_data, commandBuffer);
+        if (!skip_call) {
             updateResourceTrackingOnDraw(pCB);
         }
-        skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdDrawIndexed");
+        skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdDrawIndexed");
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
                                                         firstInstance);
 }
@@ -6821,153 +7166,157 @@
 VKAPI_ATTR void VKAPI_CALL
 CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-    bool skipCall = false;
+    bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory mem;
-    // MTMTODO : merge with code below
-    skipCall =
-        get_mem_binding_from_object(dev_data, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, mem, "vkCmdDrawIndirect");
-    GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
-    if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_DRAWINDIRECT, "vkCmdDrawIndirect()");
-        pCB->drawCount[DRAW_INDIRECT]++;
-        skipCall |= validate_and_update_draw_state(dev_data, pCB, false, VK_PIPELINE_BIND_POINT_GRAPHICS);
-        skipCall |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
+
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto buff_node = getBufferNode(dev_data, buffer);
+    if (cb_node && buff_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, buff_node, "vkCmdDrawIndirect()");
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, buff_node, "vkCmdDrawIndirect()");
+        skip_call |= addCmd(dev_data, cb_node, CMD_DRAWINDIRECT, "vkCmdDrawIndirect()");
+        cb_node->drawCount[DRAW_INDIRECT]++;
+        skip_call |= validate_and_update_draw_state(dev_data, cb_node, false, VK_PIPELINE_BIND_POINT_GRAPHICS);
+        skip_call |= markStoreImagesAndBuffersAsWritten(dev_data, cb_node);
         // TODO : Need to pass commandBuffer as srcObj here
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_NONE, "DS",
-                            "vkCmdDrawIndirect() call 0x%" PRIx64 ", reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
-        skipCall |= synchAndPrintDSConfig(dev_data, commandBuffer);
-        if (!skipCall) {
-            updateResourceTrackingOnDraw(pCB);
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
+                             VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_NONE, "DS",
+                             "vkCmdDrawIndirect() call 0x%" PRIx64 ", reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
+        skip_call |= synchAndPrintDSConfig(dev_data, commandBuffer);
+        if (!skip_call) {
+            updateResourceTrackingOnDraw(cb_node);
         }
-        skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdDrawIndirect");
+        skip_call |= outsideRenderPass(dev_data, cb_node, "vkCmdDrawIndirect()");
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory mem;
-    // MTMTODO : merge with code below
-    skipCall =
-        get_mem_binding_from_object(dev_data, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, mem, "vkCmdDrawIndexedIndirect");
-    GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
-    if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_DRAWINDEXEDINDIRECT, "vkCmdDrawIndexedIndirect()");
-        pCB->drawCount[DRAW_INDEXED_INDIRECT]++;
-        skipCall |= validate_and_update_draw_state(dev_data, pCB, true, VK_PIPELINE_BIND_POINT_GRAPHICS);
-        skipCall |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
+
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto buff_node = getBufferNode(dev_data, buffer);
+    if (cb_node && buff_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, buff_node, "vkCmdDrawIndexedIndirect()");
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, buff_node, "vkCmdDrawIndexedIndirect()");
+        skip_call |= addCmd(dev_data, cb_node, CMD_DRAWINDEXEDINDIRECT, "vkCmdDrawIndexedIndirect()");
+        cb_node->drawCount[DRAW_INDEXED_INDIRECT]++;
+        skip_call |= validate_and_update_draw_state(dev_data, cb_node, true, VK_PIPELINE_BIND_POINT_GRAPHICS);
+        skip_call |= markStoreImagesAndBuffersAsWritten(dev_data, cb_node);
         // TODO : Need to pass commandBuffer as srcObj here
-        skipCall |=
+        skip_call |=
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
                     __LINE__, DRAWSTATE_NONE, "DS", "vkCmdDrawIndexedIndirect() call 0x%" PRIx64 ", reporting DS state:",
                     g_drawCount[DRAW_INDEXED_INDIRECT]++);
-        skipCall |= synchAndPrintDSConfig(dev_data, commandBuffer);
-        if (!skipCall) {
-            updateResourceTrackingOnDraw(pCB);
+        skip_call |= synchAndPrintDSConfig(dev_data, commandBuffer);
+        if (!skip_call) {
+            updateResourceTrackingOnDraw(cb_node);
         }
-        skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdDrawIndexedIndirect");
+        skip_call |= outsideRenderPass(dev_data, cb_node, "vkCmdDrawIndexedIndirect()");
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= validate_and_update_draw_state(dev_data, pCB, false, VK_PIPELINE_BIND_POINT_COMPUTE);
-        // TODO : Call below is temporary until call above can be re-enabled
-        update_shader_storage_images_and_buffers(dev_data, pCB);
-        skipCall |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
-        skipCall |= addCmd(dev_data, pCB, CMD_DISPATCH, "vkCmdDispatch()");
-        skipCall |= insideRenderPass(dev_data, pCB, "vkCmdDispatch");
+        skip_call |= validate_and_update_draw_state(dev_data, pCB, false, VK_PIPELINE_BIND_POINT_COMPUTE);
+        skip_call |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
+        skip_call |= addCmd(dev_data, pCB, CMD_DISPATCH, "vkCmdDispatch()");
+        skip_call |= insideRenderPass(dev_data, pCB, "vkCmdDispatch");
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdDispatch(commandBuffer, x, y, z);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory mem;
-    skipCall =
-        get_mem_binding_from_object(dev_data, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, mem, "vkCmdDispatchIndirect");
-    GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
-    if (pCB) {
-        skipCall |= validate_and_update_draw_state(dev_data, pCB, false, VK_PIPELINE_BIND_POINT_COMPUTE);
-        // TODO : Call below is temporary until call above can be re-enabled
-        update_shader_storage_images_and_buffers(dev_data, pCB);
-        skipCall |= markStoreImagesAndBuffersAsWritten(dev_data, pCB);
-        skipCall |= addCmd(dev_data, pCB, CMD_DISPATCHINDIRECT, "vkCmdDispatchIndirect()");
-        skipCall |= insideRenderPass(dev_data, pCB, "vkCmdDispatchIndirect");
+
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto buff_node = getBufferNode(dev_data, buffer);
+    if (cb_node && buff_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, buff_node, "vkCmdDispatchIndirect()");
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, buff_node, "vkCmdDispatchIndirect()");
+        skip_call |= validate_and_update_draw_state(dev_data, cb_node, false, VK_PIPELINE_BIND_POINT_COMPUTE);
+        skip_call |= markStoreImagesAndBuffersAsWritten(dev_data, cb_node);
+        skip_call |= addCmd(dev_data, cb_node, CMD_DISPATCHINDIRECT, "vkCmdDispatchIndirect()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdDispatchIndirect()");
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdDispatchIndirect(commandBuffer, buffer, offset);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
                                          uint32_t regionCount, const VkBufferCopy *pRegions) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory src_mem, dst_mem;
-    skipCall = get_mem_binding_from_object(dev_data, (uint64_t)srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &src_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, src_mem, "vkCmdCopyBuffer");
-    skipCall |= get_mem_binding_from_object(dev_data, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &dst_mem);
 
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, dst_mem, "vkCmdCopyBuffer");
-    // Validate that SRC & DST buffers have correct usage flags set
-    skipCall |= validate_buffer_usage_flags(dev_data, srcBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true,
-                                            "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
-    skipCall |= validate_buffer_usage_flags(dev_data, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true,
-                                            "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
-        std::function<bool()> function = [=]() { return validate_memory_is_valid(dev_data, src_mem, "vkCmdCopyBuffer()"); };
-        cb_data->second->validate_functions.push_back(function);
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto src_buff_node = getBufferNode(dev_data, srcBuffer);
+    auto dst_buff_node = getBufferNode(dev_data, dstBuffer);
+    if (cb_node && src_buff_node && dst_buff_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, src_buff_node, "vkCmdCopyBuffer()");
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, dst_buff_node, "vkCmdCopyBuffer()");
+        // Update bindings between buffers and cmd buffer
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, src_buff_node, "vkCmdCopyBuffer()");
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, dst_buff_node, "vkCmdCopyBuffer()");
+        // Validate that SRC & DST buffers have correct usage flags set
+        skip_call |= ValidateBufferUsageFlags(dev_data, src_buff_node, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyBuffer()",
+                                              "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
+        skip_call |= ValidateBufferUsageFlags(dev_data, dst_buff_node, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyBuffer()",
+                                              "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
+
+        std::function<bool()> function = [=]() {
+            return validate_memory_is_valid(dev_data, src_buff_node->mem, "vkCmdCopyBuffer()");
+        };
+        cb_node->validate_functions.push_back(function);
         function = [=]() {
-            set_memory_valid(dev_data, dst_mem, true);
+            set_memory_valid(dev_data, dst_buff_node->mem, true);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_COPYBUFFER, "vkCmdCopyBuffer()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdCopyBuffer");
+        skip_call |= addCmd(dev_data, cb_node, CMD_COPYBUFFER, "vkCmdCopyBuffer()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyBuffer()");
+    } else {
+        // Param_checker will flag errors on invalid objects, just assert here as debugging aid
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
 }
 
-static bool VerifySourceImageLayout(VkCommandBuffer cmdBuffer, VkImage srcImage, VkImageSubresourceLayers subLayers,
-                                    VkImageLayout srcImageLayout) {
+static bool VerifySourceImageLayout(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, VkImage srcImage,
+                                    VkImageSubresourceLayers subLayers, VkImageLayout srcImageLayout) {
     bool skip_call = false;
 
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
-    GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer);
     for (uint32_t i = 0; i < subLayers.layerCount; ++i) {
         uint32_t layer = i + subLayers.baseArrayLayer;
         VkImageSubresource sub = {subLayers.aspectMask, subLayers.mipLevel, layer};
         IMAGE_CMD_BUF_LAYOUT_NODE node;
-        if (!FindLayout(pCB, srcImage, sub, node)) {
-            SetLayout(pCB, srcImage, sub, IMAGE_CMD_BUF_LAYOUT_NODE(srcImageLayout, srcImageLayout));
+        if (!FindLayout(cb_node, srcImage, sub, node)) {
+            SetLayout(cb_node, srcImage, sub, IMAGE_CMD_BUF_LAYOUT_NODE(srcImageLayout, srcImageLayout));
             continue;
         }
         if (node.layout != srcImageLayout) {
@@ -6981,10 +7330,14 @@
     }
     if (srcImageLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
         if (srcImageLayout == VK_IMAGE_LAYOUT_GENERAL) {
-            // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning.
-            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0,
-                                 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                 "Layout for input image should be TRANSFER_SRC_OPTIMAL instead of GENERAL.");
+            // TODO : Can we deal with image node from the top of call tree and avoid map look-up here?
+            auto image_node = getImageNode(dev_data, srcImage);
+            if (image_node->createInfo.tiling != VK_IMAGE_TILING_LINEAR) {
+                // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning.
+                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                     (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                                     "Layout for input image should be TRANSFER_SRC_OPTIMAL instead of GENERAL.");
+            }
         } else {
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                                  DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", "Layout for input image is %s but can only be "
@@ -6995,18 +7348,16 @@
     return skip_call;
 }
 
-static bool VerifyDestImageLayout(VkCommandBuffer cmdBuffer, VkImage destImage, VkImageSubresourceLayers subLayers,
-                                  VkImageLayout destImageLayout) {
+static bool VerifyDestImageLayout(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, VkImage destImage,
+                                  VkImageSubresourceLayers subLayers, VkImageLayout destImageLayout) {
     bool skip_call = false;
 
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
-    GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer);
     for (uint32_t i = 0; i < subLayers.layerCount; ++i) {
         uint32_t layer = i + subLayers.baseArrayLayer;
         VkImageSubresource sub = {subLayers.aspectMask, subLayers.mipLevel, layer};
         IMAGE_CMD_BUF_LAYOUT_NODE node;
-        if (!FindLayout(pCB, destImage, sub, node)) {
-            SetLayout(pCB, destImage, sub, IMAGE_CMD_BUF_LAYOUT_NODE(destImageLayout, destImageLayout));
+        if (!FindLayout(cb_node, destImage, sub, node)) {
+            SetLayout(cb_node, destImage, sub, IMAGE_CMD_BUF_LAYOUT_NODE(destImageLayout, destImageLayout));
             continue;
         }
         if (node.layout != destImageLayout) {
@@ -7019,10 +7370,13 @@
     }
     if (destImageLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
         if (destImageLayout == VK_IMAGE_LAYOUT_GENERAL) {
-            // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning.
-            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0,
-                                 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                 "Layout for output image should be TRANSFER_DST_OPTIMAL instead of GENERAL.");
+            auto image_node = getImageNode(dev_data, destImage);
+            if (image_node->createInfo.tiling != VK_IMAGE_TILING_LINEAR) {
+                // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning.
+                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                     (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                                     "Layout for output image should be TRANSFER_DST_OPTIMAL instead of GENERAL.");
+            }
         } else {
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                                  DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", "Layout for output image is %s but can only be "
@@ -7036,41 +7390,45 @@
 VKAPI_ATTR void VKAPI_CALL
 CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
              VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy *pRegions) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory src_mem, dst_mem;
-    // Validate that src & dst images have correct usage flags set
-    skipCall = get_mem_binding_from_object(dev_data, (uint64_t)srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &src_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, src_mem, "vkCmdCopyImage");
 
-    skipCall |= get_mem_binding_from_object(dev_data, (uint64_t)dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &dst_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, dst_mem, "vkCmdCopyImage");
-    skipCall |= validate_image_usage_flags(dev_data, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true,
-                                           "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
-    skipCall |= validate_image_usage_flags(dev_data, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true,
-                                           "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto src_img_node = getImageNode(dev_data, srcImage);
+    auto dst_img_node = getImageNode(dev_data, dstImage);
+    if (cb_node && src_img_node && dst_img_node) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_img_node, "vkCmdCopyImage()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_img_node, "vkCmdCopyImage()");
+        // Update bindings between images and cmd buffer
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, src_img_node, "vkCmdCopyImage()");
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, dst_img_node, "vkCmdCopyImage()");
+        // Validate that SRC & DST images have correct usage flags set
+        skip_call |= ValidateImageUsageFlags(dev_data, src_img_node, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyImage()",
+                                             "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
+        skip_call |= ValidateImageUsageFlags(dev_data, dst_img_node, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyImage()",
+                                             "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            return validate_memory_is_valid(dev_data, src_mem, "vkCmdCopyImage()", srcImage);
+            return validate_memory_is_valid(dev_data, src_img_node->mem, "vkCmdCopyImage()", srcImage);
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
         function = [=]() {
-            set_memory_valid(dev_data, dst_mem, true, dstImage);
+            set_memory_valid(dev_data, dst_img_node->mem, true, dstImage);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_COPYIMAGE, "vkCmdCopyImage()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdCopyImage");
+        skip_call |= addCmd(dev_data, cb_node, CMD_COPYIMAGE, "vkCmdCopyImage()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyImage()");
         for (uint32_t i = 0; i < regionCount; ++i) {
-            skipCall |= VerifySourceImageLayout(commandBuffer, srcImage, pRegions[i].srcSubresource, srcImageLayout);
-            skipCall |= VerifyDestImageLayout(commandBuffer, dstImage, pRegions[i].dstSubresource, dstImageLayout);
+            skip_call |= VerifySourceImageLayout(dev_data, cb_node, srcImage, pRegions[i].srcSubresource, srcImageLayout);
+            skip_call |= VerifyDestImageLayout(dev_data, cb_node, dstImage, pRegions[i].dstSubresource, dstImageLayout);
         }
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
                                                       regionCount, pRegions);
 }
@@ -7078,38 +7436,41 @@
 VKAPI_ATTR void VKAPI_CALL
 CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
              VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory src_mem, dst_mem;
-    // Validate that src & dst images have correct usage flags set
-    skipCall = get_mem_binding_from_object(dev_data, (uint64_t)srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &src_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, src_mem, "vkCmdBlitImage");
 
-    skipCall |= get_mem_binding_from_object(dev_data, (uint64_t)dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &dst_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, dst_mem, "vkCmdBlitImage");
-    skipCall |= validate_image_usage_flags(dev_data, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true,
-                                           "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
-    skipCall |= validate_image_usage_flags(dev_data, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true,
-                                           "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
-
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto src_img_node = getImageNode(dev_data, srcImage);
+    auto dst_img_node = getImageNode(dev_data, dstImage);
+    if (cb_node && src_img_node && dst_img_node) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_img_node, "vkCmdBlitImage()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_img_node, "vkCmdBlitImage()");
+        // Update bindings between images and cmd buffer
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, src_img_node, "vkCmdBlitImage()");
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, dst_img_node, "vkCmdBlitImage()");
+        // Validate that SRC & DST images have correct usage flags set
+        skip_call |= ValidateImageUsageFlags(dev_data, src_img_node, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdBlitImage()",
+                                             "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
+        skip_call |= ValidateImageUsageFlags(dev_data, dst_img_node, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdBlitImage()",
+                                             "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            return validate_memory_is_valid(dev_data, src_mem, "vkCmdBlitImage()", srcImage);
+            return validate_memory_is_valid(dev_data, src_img_node->mem, "vkCmdBlitImage()", srcImage);
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
         function = [=]() {
-            set_memory_valid(dev_data, dst_mem, true, dstImage);
+            set_memory_valid(dev_data, dst_img_node->mem, true, dstImage);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_BLITIMAGE, "vkCmdBlitImage()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdBlitImage");
+        skip_call |= addCmd(dev_data, cb_node, CMD_BLITIMAGE, "vkCmdBlitImage()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdBlitImage()");
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
                                                       regionCount, pRegions, filter);
 }
@@ -7117,38 +7478,40 @@
 VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
                                                 VkImage dstImage, VkImageLayout dstImageLayout,
                                                 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory dst_mem, src_mem;
-    skipCall = get_mem_binding_from_object(dev_data, (uint64_t)dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &dst_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, dst_mem, "vkCmdCopyBufferToImage");
 
-    skipCall |= get_mem_binding_from_object(dev_data, (uint64_t)srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &src_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, src_mem, "vkCmdCopyBufferToImage");
-    // Validate that src buff & dst image have correct usage flags set
-    skipCall |= validate_buffer_usage_flags(dev_data, srcBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyBufferToImage()",
-                                            "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
-    skipCall |= validate_image_usage_flags(dev_data, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyBufferToImage()",
-                                           "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto src_buff_node = getBufferNode(dev_data, srcBuffer);
+    auto dst_img_node = getImageNode(dev_data, dstImage);
+    if (cb_node && src_buff_node && dst_img_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, src_buff_node, "vkCmdCopyBufferToImage()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_img_node, "vkCmdCopyBufferToImage()");
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, src_buff_node, "vkCmdCopyBufferToImage()");
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, dst_img_node, "vkCmdCopyBufferToImage()");
+        skip_call |= ValidateBufferUsageFlags(dev_data, src_buff_node, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true,
+                                              "vkCmdCopyBufferToImage()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
+        skip_call |= ValidateImageUsageFlags(dev_data, dst_img_node, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true,
+                                             "vkCmdCopyBufferToImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            set_memory_valid(dev_data, dst_mem, true, dstImage);
+            set_memory_valid(dev_data, dst_img_node->mem, true, dstImage);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
-        function = [=]() { return validate_memory_is_valid(dev_data, src_mem, "vkCmdCopyBufferToImage()"); };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
+        function = [=]() { return validate_memory_is_valid(dev_data, src_buff_node->mem, "vkCmdCopyBufferToImage()"); };
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_COPYBUFFERTOIMAGE, "vkCmdCopyBufferToImage()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdCopyBufferToImage");
+        skip_call |= addCmd(dev_data, cb_node, CMD_COPYBUFFERTOIMAGE, "vkCmdCopyBufferToImage()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyBufferToImage()");
         for (uint32_t i = 0; i < regionCount; ++i) {
-            skipCall |= VerifyDestImageLayout(commandBuffer, dstImage, pRegions[i].imageSubresource, dstImageLayout);
+            skip_call |= VerifyDestImageLayout(dev_data, cb_node, dstImage, pRegions[i].imageSubresource, dstImageLayout);
         }
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount,
                                                               pRegions);
 }
@@ -7156,112 +7519,119 @@
 VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
                                                 VkImageLayout srcImageLayout, VkBuffer dstBuffer,
                                                 uint32_t regionCount, const VkBufferImageCopy *pRegions) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory src_mem, dst_mem;
-    skipCall = get_mem_binding_from_object(dev_data, (uint64_t)srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &src_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, src_mem, "vkCmdCopyImageToBuffer");
 
-    skipCall |= get_mem_binding_from_object(dev_data, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &dst_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, dst_mem, "vkCmdCopyImageToBuffer");
-    // Validate that dst buff & src image have correct usage flags set
-    skipCall |= validate_image_usage_flags(dev_data, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyImageToBuffer()",
-                                           "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
-    skipCall |= validate_buffer_usage_flags(dev_data, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyImageToBuffer()",
-                                            "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
-
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto src_img_node = getImageNode(dev_data, srcImage);
+    auto dst_buff_node = getBufferNode(dev_data, dstBuffer);
+    if (cb_node && src_img_node && dst_buff_node) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_img_node, "vkCmdCopyImageToBuffer()");
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, dst_buff_node, "vkCmdCopyImageToBuffer()");
+        // Update bindings between buffer/image and cmd buffer
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, src_img_node, "vkCmdCopyImageToBuffer()");
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, dst_buff_node, "vkCmdCopyImageToBuffer()");
+        // Validate that SRC image & DST buffer have correct usage flags set
+        skip_call |= ValidateImageUsageFlags(dev_data, src_img_node, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true,
+                                             "vkCmdCopyImageToBuffer()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
+        skip_call |= ValidateBufferUsageFlags(dev_data, dst_buff_node, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true,
+                                              "vkCmdCopyImageToBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            return validate_memory_is_valid(dev_data, src_mem, "vkCmdCopyImageToBuffer()", srcImage);
+            return validate_memory_is_valid(dev_data, src_img_node->mem, "vkCmdCopyImageToBuffer()", srcImage);
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
         function = [=]() {
-            set_memory_valid(dev_data, dst_mem, true);
+            set_memory_valid(dev_data, dst_buff_node->mem, true);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_COPYIMAGETOBUFFER, "vkCmdCopyImageToBuffer()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdCopyImageToBuffer");
+        skip_call |= addCmd(dev_data, cb_node, CMD_COPYIMAGETOBUFFER, "vkCmdCopyImageToBuffer()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyImageToBuffer()");
         for (uint32_t i = 0; i < regionCount; ++i) {
-            skipCall |= VerifySourceImageLayout(commandBuffer, srcImage, pRegions[i].imageSubresource, srcImageLayout);
+            skip_call |= VerifySourceImageLayout(dev_data, cb_node, srcImage, pRegions[i].imageSubresource, srcImageLayout);
         }
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount,
                                                               pRegions);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
                                            VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory mem;
-    skipCall =
-        get_mem_binding_from_object(dev_data, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, mem, "vkCmdUpdateBuffer");
-    // Validate that dst buff has correct usage flags set
-    skipCall |= validate_buffer_usage_flags(dev_data, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdUpdateBuffer()",
-                                            "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
 
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto dst_buff_node = getBufferNode(dev_data, dstBuffer);
+    if (cb_node && dst_buff_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, dst_buff_node, "vkCmdUpdateBuffer()");
+        // Update bindings between buffer and cmd buffer
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, dst_buff_node, "vkCmdUpdateBuffer()");
+        // Validate that DST buffer has correct usage flags set
+        skip_call |= ValidateBufferUsageFlags(dev_data, dst_buff_node, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true,
+                                              "vkCmdUpdateBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            set_memory_valid(dev_data, mem, true);
+            set_memory_valid(dev_data, dst_buff_node->mem, true);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_UPDATEBUFFER, "vkCmdUpdateBuffer()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdCopyUpdateBuffer");
+        skip_call |= addCmd(dev_data, cb_node, CMD_UPDATEBUFFER, "vkCmdUpdateBuffer()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyUpdateBuffer()");
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory mem;
-    skipCall =
-        get_mem_binding_from_object(dev_data, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, mem, "vkCmdFillBuffer");
-    // Validate that dst buff has correct usage flags set
-    skipCall |= validate_buffer_usage_flags(dev_data, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdFillBuffer()",
-                                            "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
 
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto dst_buff_node = getBufferNode(dev_data, dstBuffer);
+    if (cb_node && dst_buff_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, dst_buff_node, "vkCmdFillBuffer()");
+        // Update bindings between buffer and cmd buffer
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, dst_buff_node, "vkCmdFillBuffer()");
+        // Validate that DST buffer has correct usage flags set
+        skip_call |= ValidateBufferUsageFlags(dev_data, dst_buff_node, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdFillBuffer()",
+                                              "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            set_memory_valid(dev_data, mem, true);
+            set_memory_valid(dev_data, dst_buff_node->mem, true);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_FILLBUFFER, "vkCmdFillBuffer()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdCopyFillBuffer");
+        skip_call |= addCmd(dev_data, cb_node, CMD_FILLBUFFER, "vkCmdFillBuffer()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyFillBuffer()");
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
                                                const VkClearAttachment *pAttachments, uint32_t rectCount,
                                                const VkClearRect *pRects) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_CLEARATTACHMENTS, "vkCmdClearAttachments()");
+        skip_call |= addCmd(dev_data, pCB, CMD_CLEARATTACHMENTS, "vkCmdClearAttachments()");
         // Warn if this is issued prior to Draw Cmd and clearing the entire attachment
         if (!hasDrawCmd(pCB) && (pCB->activeRenderPassBeginInfo.renderArea.extent.width == pRects[0].rect.extent.width) &&
             (pCB->activeRenderPassBeginInfo.renderArea.extent.height == pRects[0].rect.extent.height)) {
@@ -7270,13 +7640,13 @@
             // Can we make this warning more specific? I'd like to avoid triggering this test if we can tell it's a use that must
             // call CmdClearAttachments
             // Otherwise this seems more like a performance warning.
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 0, DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS",
-                                "vkCmdClearAttachments() issued on CB object 0x%" PRIxLEAST64 " prior to any Draw Cmds."
-                                " It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw.",
-                                (uint64_t)(commandBuffer));
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 0, DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS",
+                                 "vkCmdClearAttachments() issued on CB object 0x%" PRIxLEAST64 " prior to any Draw Cmds."
+                                 " It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw.",
+                                 (uint64_t)(commandBuffer));
         }
-        skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdClearAttachments");
+        skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdClearAttachments()");
     }
 
     // Validate that attachment is in reference list of active subpass
@@ -7295,7 +7665,7 @@
                     }
                 }
                 if (!found) {
-                    skipCall |= log_msg(
+                    skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)commandBuffer, __LINE__, DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, "DS",
                         "vkCmdClearAttachments() attachment index %d not found in attachment reference array of active subpass %d",
@@ -7306,7 +7676,7 @@
                     (pSD->pDepthStencilAttachment->attachment ==
                      VK_ATTACHMENT_UNUSED)) { // Says no DS will be used in active subpass
 
-                    skipCall |= log_msg(
+                    skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)commandBuffer, __LINE__, DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, "DS",
                         "vkCmdClearAttachments() attachment index %d does not match depthStencilAttachment.attachment (%d) found "
@@ -7319,33 +7689,36 @@
         }
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
                                               VkImageLayout imageLayout, const VkClearColorValue *pColor,
                                               uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
-    VkDeviceMemory mem;
-    skipCall = get_mem_binding_from_object(dev_data, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, mem, "vkCmdClearColorImage");
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto img_node = getImageNode(dev_data, image);
+    if (cb_node && img_node) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, img_node, "vkCmdClearColorImage()");
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, img_node, "vkCmdClearColorImage()");
         std::function<bool()> function = [=]() {
-            set_memory_valid(dev_data, mem, true, image);
+            set_memory_valid(dev_data, img_node->mem, true, image);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_CLEARCOLORIMAGE, "vkCmdClearColorImage()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdClearColorImage");
+        skip_call |= addCmd(dev_data, cb_node, CMD_CLEARCOLORIMAGE, "vkCmdClearColorImage()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdClearColorImage()");
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
 }
 
@@ -7353,26 +7726,29 @@
 CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
                           const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
                           const VkImageSubresourceRange *pRanges) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
-    VkDeviceMemory mem;
-    skipCall = get_mem_binding_from_object(dev_data, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, mem, "vkCmdClearDepthStencilImage");
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto img_node = getImageNode(dev_data, image);
+    if (cb_node && img_node) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, img_node, "vkCmdClearDepthStencilImage()");
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, img_node, "vkCmdClearDepthStencilImage()");
         std::function<bool()> function = [=]() {
-            set_memory_valid(dev_data, mem, true, image);
+            set_memory_valid(dev_data, img_node->mem, true, image);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_CLEARDEPTHSTENCILIMAGE, "vkCmdClearDepthStencilImage()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdClearDepthStencilImage");
+        skip_call |= addCmd(dev_data, cb_node, CMD_CLEARDEPTHSTENCILIMAGE, "vkCmdClearDepthStencilImage()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdClearDepthStencilImage()");
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount,
                                                                    pRanges);
 }
@@ -7380,32 +7756,36 @@
 VKAPI_ATTR void VKAPI_CALL
 CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
                 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    VkDeviceMemory src_mem, dst_mem;
-    skipCall = get_mem_binding_from_object(dev_data, (uint64_t)srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &src_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, src_mem, "vkCmdResolveImage");
 
-    skipCall |= get_mem_binding_from_object(dev_data, (uint64_t)dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &dst_mem);
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, dst_mem, "vkCmdResolveImage");
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto src_img_node = getImageNode(dev_data, srcImage);
+    auto dst_img_node = getImageNode(dev_data, dstImage);
+    if (cb_node && src_img_node && dst_img_node) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_img_node, "vkCmdResolveImage()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_img_node, "vkCmdResolveImage()");
+        // Update bindings between images and cmd buffer
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, src_img_node, "vkCmdCopyImage()");
+        skip_call |= addCommandBufferBindingImage(dev_data, cb_node, dst_img_node, "vkCmdCopyImage()");
         std::function<bool()> function = [=]() {
-            return validate_memory_is_valid(dev_data, src_mem, "vkCmdResolveImage()", srcImage);
+            return validate_memory_is_valid(dev_data, src_img_node->mem, "vkCmdResolveImage()", srcImage);
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
         function = [=]() {
-            set_memory_valid(dev_data, dst_mem, true, dstImage);
+            set_memory_valid(dev_data, dst_img_node->mem, true, dstImage);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
+        cb_node->validate_functions.push_back(function);
 
-        skipCall |= addCmd(dev_data, cb_data->second, CMD_RESOLVEIMAGE, "vkCmdResolveImage()");
-        skipCall |= insideRenderPass(dev_data, cb_data->second, "vkCmdResolveImage");
+        skip_call |= addCmd(dev_data, cb_node, CMD_RESOLVEIMAGE, "vkCmdResolveImage()");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdResolveImage()");
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
                                                          regionCount, pRegions);
 }
@@ -7425,13 +7805,19 @@
 
 VKAPI_ATTR void VKAPI_CALL
 CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_SETEVENT, "vkCmdSetEvent()");
-        skipCall |= insideRenderPass(dev_data, pCB, "vkCmdSetEvent");
+        skip_call |= addCmd(dev_data, pCB, CMD_SETEVENT, "vkCmdSetEvent()");
+        skip_call |= insideRenderPass(dev_data, pCB, "vkCmdSetEvent");
+        auto event_node = getEventNode(dev_data, event);
+        if (event_node) {
+            addCommandBufferBinding(&event_node->cb_bindings,
+                                    {reinterpret_cast<uint64_t &>(event), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT}, pCB);
+            event_node->cb_bindings.insert(pCB);
+        }
         pCB->events.push_back(event);
         if (!pCB->waitedEvents.count(event)) {
             pCB->writeEventsBeforeWait.push_back(event);
@@ -7441,19 +7827,25 @@
         pCB->eventUpdates.push_back(eventUpdate);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdSetEvent(commandBuffer, event, stageMask);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_RESETEVENT, "vkCmdResetEvent()");
-        skipCall |= insideRenderPass(dev_data, pCB, "vkCmdResetEvent");
+        skip_call |= addCmd(dev_data, pCB, CMD_RESETEVENT, "vkCmdResetEvent()");
+        skip_call |= insideRenderPass(dev_data, pCB, "vkCmdResetEvent");
+        auto event_node = getEventNode(dev_data, event);
+        if (event_node) {
+            addCommandBufferBinding(&event_node->cb_bindings,
+                                    {reinterpret_cast<uint64_t &>(event), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT}, pCB);
+            event_node->cb_bindings.insert(pCB);
+        }
         pCB->events.push_back(event);
         if (!pCB->waitedEvents.count(event)) {
             pCB->writeEventsBeforeWait.push_back(event);
@@ -7463,7 +7855,7 @@
         pCB->eventUpdates.push_back(eventUpdate);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdResetEvent(commandBuffer, event, stageMask);
 }
 
@@ -7640,11 +8032,11 @@
     }
     for (uint32_t i = 0; i < imageMemBarrierCount; ++i) {
         auto mem_barrier = &pImageMemBarriers[i];
-        auto image_data = dev_data->imageMap.find(mem_barrier->image);
-        if (image_data != dev_data->imageMap.end()) {
+        auto image_data = getImageNode(dev_data, mem_barrier->image);
+        if (image_data) {
             uint32_t src_q_f_index = mem_barrier->srcQueueFamilyIndex;
             uint32_t dst_q_f_index = mem_barrier->dstQueueFamilyIndex;
-            if (image_data->second.createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) {
+            if (image_data->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) {
                 // srcQueueFamilyIndex and dstQueueFamilyIndex must both
                 // be VK_QUEUE_FAMILY_IGNORED
                 if ((src_q_f_index != VK_QUEUE_FAMILY_IGNORED) || (dst_q_f_index != VK_QUEUE_FAMILY_IGNORED)) {
@@ -7694,36 +8086,61 @@
                                                          "PREINITIALIZED.",
                         funcName);
             }
-            auto image_data = dev_data->imageMap.find(mem_barrier->image);
+            auto image_data = getImageNode(dev_data, mem_barrier->image);
             VkFormat format = VK_FORMAT_UNDEFINED;
             uint32_t arrayLayers = 0, mipLevels = 0;
             bool imageFound = false;
-            if (image_data != dev_data->imageMap.end()) {
-                format = image_data->second.createInfo.format;
-                arrayLayers = image_data->second.createInfo.arrayLayers;
-                mipLevels = image_data->second.createInfo.mipLevels;
+            if (image_data) {
+                format = image_data->createInfo.format;
+                arrayLayers = image_data->createInfo.arrayLayers;
+                mipLevels = image_data->createInfo.mipLevels;
                 imageFound = true;
             } else if (dev_data->device_extensions.wsi_enabled) {
-                auto imageswap_data = dev_data->device_extensions.imageToSwapchainMap.find(mem_barrier->image);
-                if (imageswap_data != dev_data->device_extensions.imageToSwapchainMap.end()) {
-                    auto swapchain_data = dev_data->device_extensions.swapchainMap.find(imageswap_data->second);
-                    if (swapchain_data != dev_data->device_extensions.swapchainMap.end()) {
-                        format = swapchain_data->second->createInfo.imageFormat;
-                        arrayLayers = swapchain_data->second->createInfo.imageArrayLayers;
+                auto imageswap_data = getSwapchainFromImage(dev_data, mem_barrier->image);
+                if (imageswap_data) {
+                    auto swapchain_data = getSwapchainNode(dev_data, imageswap_data);
+                    if (swapchain_data) {
+                        format = swapchain_data->createInfo.imageFormat;
+                        arrayLayers = swapchain_data->createInfo.imageArrayLayers;
                         mipLevels = 1;
                         imageFound = true;
                     }
                 }
             }
             if (imageFound) {
-                if (vk_format_is_depth_and_stencil(format) &&
-                    (!(mem_barrier->subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ||
-                     !(mem_barrier->subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT))) {
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_INVALID_BARRIER, "DS", "%s: Image is a depth and stencil format and thus must "
-                                                             "have both VK_IMAGE_ASPECT_DEPTH_BIT and "
-                                                             "VK_IMAGE_ASPECT_STENCIL_BIT set.",
-                            funcName);
+                auto aspect_mask = mem_barrier->subresourceRange.aspectMask;
+                if (vk_format_is_depth_or_stencil(format)) {
+                    if (vk_format_is_depth_and_stencil(format)) {
+                        if (!(aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) && !(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
+                            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                    __LINE__, DRAWSTATE_INVALID_BARRIER, "DS",
+                                    "%s: Image is a depth and stencil format and thus must "
+                                    "have either one or both of VK_IMAGE_ASPECT_DEPTH_BIT and "
+                                    "VK_IMAGE_ASPECT_STENCIL_BIT set.",
+                                    funcName);
+                        }
+                    } else if (vk_format_is_depth_only(format)) {
+                        if (!(aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)) {
+                            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                    __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", "%s: Image is a depth-only format and thus must "
+                                                                               "have VK_IMAGE_ASPECT_DEPTH_BIT set.",
+                                    funcName);
+                        }
+                    } else { // stencil-only case
+                        if (!(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
+                            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                    __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", "%s: Image is a stencil-only format and thus must "
+                                                                               "have VK_IMAGE_ASPECT_STENCIL_BIT set.",
+                                    funcName);
+                        }
+                    }
+                } else { // image is a color format
+                    if (!(aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT)) {
+                        log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                DRAWSTATE_INVALID_BARRIER, "DS", "%s: Image is a color format and thus must "
+                                                                 "have VK_IMAGE_ASPECT_COLOR_BIT set.",
+                                funcName);
+                    }
                 }
                 int layerCount = (mem_barrier->subresourceRange.layerCount == VK_REMAINING_ARRAY_LAYERS)
                                      ? 1
@@ -7773,11 +8190,9 @@
                                  dev_data->phys_dev_properties.queue_family_properties.size());
         }
 
-        auto buffer_data = dev_data->bufferMap.find(mem_barrier->buffer);
-        if (buffer_data != dev_data->bufferMap.end()) {
-            VkDeviceSize buffer_size = (buffer_data->second.createInfo.sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
-                                           ? buffer_data->second.createInfo.size
-                                           : 0;
+        auto buffer_node = getBufferNode(dev_data, mem_barrier->buffer);
+        if (buffer_node) {
+            auto buffer_size = buffer_node->memSize;
             if (mem_barrier->offset >= buffer_size) {
                 skip_call |= log_msg(
                     dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
@@ -7812,14 +8227,14 @@
         if (event_data != queue_data->second.eventToStageMap.end()) {
             stageMask |= event_data->second;
         } else {
-            auto global_event_data = dev_data->eventMap.find(event);
-            if (global_event_data == dev_data->eventMap.end()) {
+            auto global_event_data = getEventNode(dev_data, event);
+            if (!global_event_data) {
                 skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,
                                      reinterpret_cast<const uint64_t &>(event), __LINE__, DRAWSTATE_INVALID_EVENT, "DS",
                                      "Event 0x%" PRIx64 " cannot be waited on if it has never been set.",
                                      reinterpret_cast<const uint64_t &>(event));
             } else {
-                stageMask |= global_event_data->second.stageMask;
+                stageMask |= global_event_data->stageMask;
             }
         }
     }
@@ -7828,10 +8243,10 @@
     if (sourceStageMask != stageMask && sourceStageMask != (stageMask | VK_PIPELINE_STAGE_HOST_BIT)) {
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                              DRAWSTATE_INVALID_EVENT, "DS", "Submitting cmdbuffer with call to VkCmdWaitEvents "
-                                                            "using srcStageMask 0x%x which must be the bitwise "
+                                                            "using srcStageMask 0x%X which must be the bitwise "
                                                             "OR of the stageMask parameters used in calls to "
                                                             "vkCmdSetEvent and VK_PIPELINE_STAGE_HOST_BIT if "
-                                                            "used with vkSetEvent but instead is 0x%x.",
+                                                            "used with vkSetEvent but instead is 0x%X.",
                              sourceStageMask, stageMask);
     }
     return skip_call;
@@ -7842,13 +8257,20 @@
               VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
               uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
               uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
         auto firstEventIndex = pCB->events.size();
         for (uint32_t i = 0; i < eventCount; ++i) {
+            auto event_node = getEventNode(dev_data, pEvents[i]);
+            if (event_node) {
+                addCommandBufferBinding(&event_node->cb_bindings,
+                                        {reinterpret_cast<const uint64_t &>(pEvents[i]), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT},
+                                        pCB);
+                event_node->cb_bindings.insert(pCB);
+            }
             pCB->waitedEvents.insert(pEvents[i]);
             pCB->events.push_back(pEvents[i]);
         }
@@ -7856,17 +8278,17 @@
             std::bind(validateEventStageMask, std::placeholders::_1, pCB, eventCount, firstEventIndex, sourceStageMask);
         pCB->eventUpdates.push_back(eventUpdate);
         if (pCB->state == CB_RECORDING) {
-            skipCall |= addCmd(dev_data, pCB, CMD_WAITEVENTS, "vkCmdWaitEvents()");
+            skip_call |= addCmd(dev_data, pCB, CMD_WAITEVENTS, "vkCmdWaitEvents()");
         } else {
-            skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdWaitEvents()");
+            skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdWaitEvents()");
         }
-        skipCall |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
-        skipCall |=
+        skip_call |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
+        skip_call |=
             ValidateBarriers("vkCmdWaitEvents", commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
                              pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask,
                                                        memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
                                                        pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
@@ -7877,19 +8299,19 @@
                    VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
                    uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
                    uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= addCmd(dev_data, pCB, CMD_PIPELINEBARRIER, "vkCmdPipelineBarrier()");
-        skipCall |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
-        skipCall |=
+        skip_call |= addCmd(dev_data, pCB, CMD_PIPELINEBARRIER, "vkCmdPipelineBarrier()");
+        skip_call |= TransitionImageLayouts(commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers);
+        skip_call |=
             ValidateBarriers("vkCmdPipelineBarrier", commandBuffer, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
                              pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
                                                             memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
                                                             pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
@@ -7910,7 +8332,7 @@
 
 VKAPI_ATTR void VKAPI_CALL
 CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
@@ -7920,22 +8342,24 @@
         if (!pCB->startedQueries.count(query)) {
             pCB->startedQueries.insert(query);
         }
-        skipCall |= addCmd(dev_data, pCB, CMD_BEGINQUERY, "vkCmdBeginQuery()");
+        skip_call |= addCmd(dev_data, pCB, CMD_BEGINQUERY, "vkCmdBeginQuery()");
+        addCommandBufferBinding(&getQueryPoolNode(dev_data, queryPool)->cb_bindings,
+                                {reinterpret_cast<uint64_t &>(queryPool), VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT}, pCB);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdBeginQuery(commandBuffer, queryPool, slot, flags);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
         QueryObject query = {queryPool, slot};
         if (!pCB->activeQueries.count(query)) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_INVALID_QUERY, "DS", "Ending a query before it was started: queryPool 0x%" PRIx64 ", index %d",
                         (uint64_t)(queryPool), slot);
@@ -7945,19 +8369,21 @@
         std::function<bool(VkQueue)> queryUpdate = std::bind(setQueryState, std::placeholders::_1, commandBuffer, query, true);
         pCB->queryUpdates.push_back(queryUpdate);
         if (pCB->state == CB_RECORDING) {
-            skipCall |= addCmd(dev_data, pCB, CMD_ENDQUERY, "VkCmdEndQuery()");
+            skip_call |= addCmd(dev_data, pCB, CMD_ENDQUERY, "VkCmdEndQuery()");
         } else {
-            skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdEndQuery()");
+            skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdEndQuery()");
         }
+        addCommandBufferBinding(&getQueryPoolNode(dev_data, queryPool)->cb_bindings,
+                                {reinterpret_cast<uint64_t &>(queryPool), VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT}, pCB);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdEndQuery(commandBuffer, queryPool, slot);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
@@ -7969,14 +8395,16 @@
             pCB->queryUpdates.push_back(queryUpdate);
         }
         if (pCB->state == CB_RECORDING) {
-            skipCall |= addCmd(dev_data, pCB, CMD_RESETQUERYPOOL, "VkCmdResetQueryPool()");
+            skip_call |= addCmd(dev_data, pCB, CMD_RESETQUERYPOOL, "VkCmdResetQueryPool()");
         } else {
-            skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdResetQueryPool()");
+            skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdResetQueryPool()");
         }
-        skipCall |= insideRenderPass(dev_data, pCB, "vkCmdQueryPool");
+        skip_call |= insideRenderPass(dev_data, pCB, "vkCmdQueryPool");
+        addCommandBufferBinding(&getQueryPoolNode(dev_data, queryPool)->cb_bindings,
+                                {reinterpret_cast<uint64_t &>(queryPool), VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT}, pCB);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
 }
 
@@ -8017,40 +8445,40 @@
 VKAPI_ATTR void VKAPI_CALL
 CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
                         VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
-#if MTMERGESOURCE
-    VkDeviceMemory mem;
-    auto cb_data = dev_data->commandBufferMap.find(commandBuffer);
-    skipCall |=
-        get_mem_binding_from_object(dev_data, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
-    if (cb_data != dev_data->commandBufferMap.end()) {
+
+    auto cb_node = getCBNode(dev_data, commandBuffer);
+    auto dst_buff_node = getBufferNode(dev_data, dstBuffer);
+    if (cb_node && dst_buff_node) {
+        skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, dst_buff_node, "vkCmdCopyQueryPoolResults()");
+        // Update bindings between buffer and cmd buffer
+        skip_call |= addCommandBufferBindingBuffer(dev_data, cb_node, dst_buff_node, "vkCmdCopyQueryPoolResults()");
+        // Validate that DST buffer has correct usage flags set
+        skip_call |= ValidateBufferUsageFlags(dev_data, dst_buff_node, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true,
+                                              "vkCmdCopyQueryPoolResults()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            set_memory_valid(dev_data, mem, true);
+            set_memory_valid(dev_data, dst_buff_node->mem, true);
             return false;
         };
-        cb_data->second->validate_functions.push_back(function);
-    }
-    skipCall |= update_cmd_buf_and_mem_references(dev_data, commandBuffer, mem, "vkCmdCopyQueryPoolResults");
-    // Validate that DST buffer has correct usage flags set
-    skipCall |= validate_buffer_usage_flags(dev_data, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true,
-                                            "vkCmdCopyQueryPoolResults()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
-#endif
-    if (pCB) {
+        cb_node->validate_functions.push_back(function);
         std::function<bool(VkQueue)> queryUpdate =
-            std::bind(validateQuery, std::placeholders::_1, pCB, queryPool, queryCount, firstQuery);
-        pCB->queryUpdates.push_back(queryUpdate);
-        if (pCB->state == CB_RECORDING) {
-            skipCall |= addCmd(dev_data, pCB, CMD_COPYQUERYPOOLRESULTS, "vkCmdCopyQueryPoolResults()");
+            std::bind(validateQuery, std::placeholders::_1, cb_node, queryPool, queryCount, firstQuery);
+        cb_node->queryUpdates.push_back(queryUpdate);
+        if (cb_node->state == CB_RECORDING) {
+            skip_call |= addCmd(dev_data, cb_node, CMD_COPYQUERYPOOLRESULTS, "vkCmdCopyQueryPoolResults()");
         } else {
-            skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdCopyQueryPoolResults()");
+            skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdCopyQueryPoolResults()");
         }
-        skipCall |= insideRenderPass(dev_data, pCB, "vkCmdCopyQueryPoolResults");
+        skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyQueryPoolResults()");
+        addCommandBufferBinding(&getQueryPoolNode(dev_data, queryPool)->cb_bindings,
+                                {reinterpret_cast<uint64_t &>(queryPool), VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT}, cb_node);
+    } else {
+        assert(0);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer,
                                                                  dstOffset, stride, flags);
 }
@@ -8058,103 +8486,97 @@
 VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
                                             VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
                                             const void *pValues) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
         if (pCB->state == CB_RECORDING) {
-            skipCall |= addCmd(dev_data, pCB, CMD_PUSHCONSTANTS, "vkCmdPushConstants()");
+            skip_call |= addCmd(dev_data, pCB, CMD_PUSHCONSTANTS, "vkCmdPushConstants()");
         } else {
-            skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdPushConstants()");
+            skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdPushConstants()");
         }
     }
-    skipCall |= validatePushConstantRange(dev_data, offset, size, "vkCmdPushConstants()");
+    skip_call |= validatePushConstantRange(dev_data, offset, size, "vkCmdPushConstants()");
     if (0 == stageFlags) {
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCmdPushConstants() call has no stageFlags set.");
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                             DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCmdPushConstants() call has no stageFlags set.");
     }
 
     // Check if push constant update is within any of the ranges with the same stage flags specified in pipeline layout.
     auto pipeline_layout = getPipelineLayout(dev_data, layout);
-    if (!pipeline_layout) {
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCmdPushConstants() Pipeline Layout 0x%" PRIx64 " not found.",
-                            (uint64_t)layout);
+    // Coalesce adjacent/overlapping pipeline ranges before checking to see if incoming range is
+    // contained in the pipeline ranges.
+    // Build a {start, end} span list for ranges with matching stage flags.
+    const auto &ranges = pipeline_layout->push_constant_ranges;
+    struct span {
+        uint32_t start;
+        uint32_t end;
+    };
+    std::vector<span> spans;
+    spans.reserve(ranges.size());
+    for (const auto &iter : ranges) {
+        if (iter.stageFlags == stageFlags) {
+            spans.push_back({iter.offset, iter.offset + iter.size});
+        }
+    }
+    if (spans.size() == 0) {
+        // There were no ranges that matched the stageFlags.
+        skip_call |=
+            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                    DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCmdPushConstants() stageFlags = 0x%" PRIx32 " do not match "
+                                                          "the stageFlags in any of the ranges in pipeline layout 0x%" PRIx64 ".",
+                    (uint32_t)stageFlags, (uint64_t)layout);
     } else {
-        // Coalesce adjacent/overlapping pipeline ranges before checking to see if incoming range is
-        // contained in the pipeline ranges.
-        // Build a {start, end} span list for ranges with matching stage flags.
-        const auto &ranges = pipeline_layout->pushConstantRanges;
-        struct span {
-            uint32_t start;
-            uint32_t end;
-        };
-        std::vector<span> spans;
-        spans.reserve(ranges.size());
-        for (const auto &iter : ranges) {
-            if (iter.stageFlags == stageFlags) {
-                spans.push_back({iter.offset, iter.offset + iter.size});
+        // Sort span list by start value.
+        struct comparer {
+            bool operator()(struct span i, struct span j) { return i.start < j.start; }
+        } my_comparer;
+        std::sort(spans.begin(), spans.end(), my_comparer);
+
+        // Examine two spans at a time.
+        std::vector<span>::iterator current = spans.begin();
+        std::vector<span>::iterator next = current + 1;
+        while (next != spans.end()) {
+            if (current->end < next->start) {
+                // There is a gap; cannot coalesce. Move to the next two spans.
+                ++current;
+                ++next;
+            } else {
+                // Coalesce the two spans.  The start of the next span
+                // is within the current span, so pick the larger of
+                // the end values to extend the current span.
+                // Then delete the next span and set next to the span after it.
+                current->end = max(current->end, next->end);
+                next = spans.erase(next);
             }
         }
-        if (spans.size() == 0) {
-            // There were no ranges that matched the stageFlags.
-            skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS",
-                                "vkCmdPushConstants() stageFlags = 0x%" PRIx32 " do not match "
-                                "the stageFlags in any of the ranges in pipeline layout 0x%" PRIx64 ".",
-                                (uint32_t)stageFlags, (uint64_t)layout);
-        } else {
-            // Sort span list by start value.
-            struct comparer {
-                bool operator()(struct span i, struct span j) { return i.start < j.start; }
-            } my_comparer;
-            std::sort(spans.begin(), spans.end(), my_comparer);
 
-            // Examine two spans at a time.
-            std::vector<span>::iterator current = spans.begin();
-            std::vector<span>::iterator next = current + 1;
-            while (next != spans.end()) {
-                if (current->end < next->start) {
-                    // There is a gap; cannot coalesce. Move to the next two spans.
-                    ++current;
-                    ++next;
-                } else {
-                    // Coalesce the two spans.  The start of the next span
-                    // is within the current span, so pick the larger of
-                    // the end values to extend the current span.
-                    // Then delete the next span and set next to the span after it.
-                    current->end = max(current->end, next->end);
-                    next = spans.erase(next);
-                }
+        // Now we can check if the incoming range is within any of the spans.
+        bool contained_in_a_range = false;
+        for (uint32_t i = 0; i < spans.size(); ++i) {
+            if ((offset >= spans[i].start) && ((uint64_t)offset + (uint64_t)size <= (uint64_t)spans[i].end)) {
+                contained_in_a_range = true;
+                break;
             }
-
-            // Now we can check if the incoming range is within any of the spans.
-            bool contained_in_a_range = false;
-            for (uint32_t i = 0; i < spans.size(); ++i) {
-                if ((offset >= spans[i].start) && ((uint64_t)offset + (uint64_t)size <= (uint64_t)spans[i].end)) {
-                    contained_in_a_range = true;
-                    break;
-                }
-            }
-            if (!contained_in_a_range) {
-                skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                    __LINE__, DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS",
-                                    "vkCmdPushConstants() Push constant range [%d, %d) "
-                                    "with stageFlags = 0x%" PRIx32 " "
-                                    "not within flag-matching ranges in pipeline layout 0x%" PRIx64 ".",
-                                    offset, offset + size, (uint32_t)stageFlags, (uint64_t)layout);
-            }
+        }
+        if (!contained_in_a_range) {
+            skip_call |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                        DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCmdPushConstants() Push constant range [%d, %d) "
+                                                              "with stageFlags = 0x%" PRIx32 " "
+                                                              "not within flag-matching ranges in pipeline layout 0x%" PRIx64 ".",
+                        offset, offset + size, (uint32_t)stageFlags, (uint64_t)layout);
         }
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t slot) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
@@ -8163,46 +8585,222 @@
         std::function<bool(VkQueue)> queryUpdate = std::bind(setQueryState, std::placeholders::_1, commandBuffer, query, true);
         pCB->queryUpdates.push_back(queryUpdate);
         if (pCB->state == CB_RECORDING) {
-            skipCall |= addCmd(dev_data, pCB, CMD_WRITETIMESTAMP, "vkCmdWriteTimestamp()");
+            skip_call |= addCmd(dev_data, pCB, CMD_WRITETIMESTAMP, "vkCmdWriteTimestamp()");
         } else {
-            skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdWriteTimestamp()");
+            skip_call |= report_error_no_cb_begin(dev_data, commandBuffer, "vkCmdWriteTimestamp()");
         }
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, slot);
 }
 
+static bool MatchUsage(layer_data *dev_data, uint32_t count, const VkAttachmentReference *attachments,
+                       const VkFramebufferCreateInfo *fbci, VkImageUsageFlagBits usage_flag) {
+    bool skip_call = false;
+
+    for (uint32_t attach = 0; attach < count; attach++) {
+        if (attachments[attach].attachment != VK_ATTACHMENT_UNUSED) {
+            // Attachment counts are verified elsewhere, but prevent an invalid access
+            if (attachments[attach].attachment < fbci->attachmentCount) {
+                const VkImageView *image_view = &fbci->pAttachments[attachments[attach].attachment];
+                VkImageViewCreateInfo *ivci = getImageViewData(dev_data, *image_view);
+                if (ivci != nullptr) {
+                    const VkImageCreateInfo *ici = &getImageNode(dev_data, ivci->image)->createInfo;
+                    if (ici != nullptr) {
+                        if ((ici->usage & usage_flag) == 0) {
+                            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                                 (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_USAGE, "DS",
+                                                 "vkCreateFramebuffer:  Framebuffer Attachment (%d) conflicts with the image's "
+                                                 "IMAGE_USAGE flags (%s).",
+                                                 attachments[attach].attachment, string_VkImageUsageFlagBits(usage_flag));
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return skip_call;
+}
+
+// Validate VkFramebufferCreateInfo which includes:
+// 1. attachmentCount equals renderPass attachmentCount
+// 2. corresponding framebuffer and renderpass attachments have matching formats
+// 3. corresponding framebuffer and renderpass attachments have matching sample counts
+// 4. fb attachments only have a single mip level
+// 5. fb attachment dimensions are each at least as large as the fb
+// 6. fb attachments use idenity swizzle
+// 7. fb attachments used by renderPass for color/input/ds have correct usage bit set
+// 8. fb dimensions are within physical device limits
+static bool ValidateFramebufferCreateInfo(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo) {
+    bool skip_call = false;
+
+    auto rp_node = getRenderPass(dev_data, pCreateInfo->renderPass);
+    if (rp_node) {
+        const VkRenderPassCreateInfo *rpci = rp_node->pCreateInfo;
+        if (rpci->attachmentCount != pCreateInfo->attachmentCount) {
+            skip_call |= log_msg(
+                dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
+                "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of %u does not match attachmentCount of %u of "
+                "renderPass (0x%" PRIxLEAST64 ") being used to create Framebuffer.",
+                pCreateInfo->attachmentCount, rpci->attachmentCount, reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass));
+        } else {
+            // attachmentCounts match, so make sure corresponding attachment details line up
+            const VkImageView *image_views = pCreateInfo->pAttachments;
+            for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
+                VkImageViewCreateInfo *ivci = getImageViewData(dev_data, image_views[i]);
+                if (ivci->format != rpci->pAttachments[i].format) {
+                    skip_call |= log_msg(
+                        dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                        reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE,
+                        "DS", "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has format of %s that does not match "
+                              "the format of "
+                              "%s used by the corresponding attachment for renderPass (0x%" PRIxLEAST64 ").",
+                        i, string_VkFormat(ivci->format), string_VkFormat(rpci->pAttachments[i].format),
+                        reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass));
+                }
+                const VkImageCreateInfo *ici = &getImageNode(dev_data, ivci->image)->createInfo;
+                if (ici->samples != rpci->pAttachments[i].samples) {
+                    skip_call |= log_msg(
+                        dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                        reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE,
+                        "DS", "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has %s samples that do not match "
+                              "the %s samples used by the corresponding attachment for renderPass (0x%" PRIxLEAST64 ").",
+                        i, string_VkSampleCountFlagBits(ici->samples), string_VkSampleCountFlagBits(rpci->pAttachments[i].samples),
+                        reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass));
+                }
+                // Verify that view only has a single mip level
+                if (ivci->subresourceRange.levelCount != 1) {
+                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+                                         __LINE__, DRAWSTATE_INVALID_FRAMEBUFFER_CREATE_INFO, "DS",
+                                         "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has mip levelCount of %u "
+                                         "but only a single mip level (levelCount ==  1) is allowed when creating a Framebuffer.",
+                                         i, ivci->subresourceRange.levelCount);
+                }
+                const uint32_t mip_level = ivci->subresourceRange.baseMipLevel;
+                uint32_t mip_width = max(1u, ici->extent.width >> mip_level);
+                uint32_t mip_height = max(1u, ici->extent.height >> mip_level);
+                if ((ivci->subresourceRange.layerCount < pCreateInfo->layers) || (mip_width < pCreateInfo->width) ||
+                    (mip_height < pCreateInfo->height)) {
+                    skip_call |=
+                        log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
+                                DRAWSTATE_INVALID_FRAMEBUFFER_CREATE_INFO, "DS",
+                                "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u mip level %u has dimensions smaller "
+                                "than the corresponding "
+                                "framebuffer dimensions. Attachment dimensions must be at least as large. Here are the respective "
+                                "dimensions for "
+                                "attachment #%u, framebuffer:\n"
+                                "width: %u, %u\n"
+                                "height: %u, %u\n"
+                                "layerCount: %u, %u\n",
+                                i, ivci->subresourceRange.baseMipLevel, i, mip_width, pCreateInfo->width, mip_height,
+                                pCreateInfo->height, ivci->subresourceRange.layerCount, pCreateInfo->layers);
+                }
+                if (((ivci->components.r != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci->components.r != VK_COMPONENT_SWIZZLE_R)) ||
+                    ((ivci->components.g != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci->components.g != VK_COMPONENT_SWIZZLE_G)) ||
+                    ((ivci->components.b != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci->components.b != VK_COMPONENT_SWIZZLE_B)) ||
+                    ((ivci->components.a != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci->components.a != VK_COMPONENT_SWIZZLE_A))) {
+                    skip_call |= log_msg(
+                        dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
+                        DRAWSTATE_INVALID_FRAMEBUFFER_CREATE_INFO, "DS",
+                        "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has non-identy swizzle. All framebuffer "
+                        "attachments must have been created with the identity swizzle. Here are the actual swizzle values:\n"
+                        "r swizzle = %s\n"
+                        "g swizzle = %s\n"
+                        "b swizzle = %s\n"
+                        "a swizzle = %s\n",
+                        i, string_VkComponentSwizzle(ivci->components.r), string_VkComponentSwizzle(ivci->components.g),
+                        string_VkComponentSwizzle(ivci->components.b), string_VkComponentSwizzle(ivci->components.a));
+                }
+            }
+        }
+        // Verify correct attachment usage flags
+        for (uint32_t subpass = 0; subpass < rpci->subpassCount; subpass++) {
+            // Verify input attachments:
+            skip_call |= MatchUsage(dev_data, rpci->pSubpasses[subpass].inputAttachmentCount,
+                                    rpci->pSubpasses[subpass].pInputAttachments, pCreateInfo, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
+            // Verify color attachments:
+            skip_call |= MatchUsage(dev_data, rpci->pSubpasses[subpass].colorAttachmentCount,
+                                    rpci->pSubpasses[subpass].pColorAttachments, pCreateInfo, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
+            // Verify depth/stencil attachments:
+            if (rpci->pSubpasses[subpass].pDepthStencilAttachment != nullptr) {
+                skip_call |= MatchUsage(dev_data, 1, rpci->pSubpasses[subpass].pDepthStencilAttachment, pCreateInfo,
+                                        VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+            }
+        }
+    } else {
+        skip_call |=
+            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                    reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass), __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
+                    "vkCreateFramebuffer(): Attempt to create framebuffer with invalid renderPass (0x%" PRIxLEAST64 ").",
+                    reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass));
+    }
+    // Verify FB dimensions are within physical device limits
+    if ((pCreateInfo->height > dev_data->phys_dev_properties.properties.limits.maxFramebufferHeight) ||
+        (pCreateInfo->width > dev_data->phys_dev_properties.properties.limits.maxFramebufferWidth) ||
+        (pCreateInfo->layers > dev_data->phys_dev_properties.properties.limits.maxFramebufferLayers)) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
+                             DRAWSTATE_INVALID_FRAMEBUFFER_CREATE_INFO, "DS",
+                             "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo dimensions exceed physical device limits. "
+                             "Here are the respective dimensions: requested, device max:\n"
+                             "width: %u, %u\n"
+                             "height: %u, %u\n"
+                             "layerCount: %u, %u\n",
+                             pCreateInfo->width, dev_data->phys_dev_properties.properties.limits.maxFramebufferWidth,
+                             pCreateInfo->height, dev_data->phys_dev_properties.properties.limits.maxFramebufferHeight,
+                             pCreateInfo->layers, dev_data->phys_dev_properties.properties.limits.maxFramebufferLayers);
+    }
+    return skip_call;
+}
+
+// Validate VkFramebufferCreateInfo state prior to calling down chain to create Framebuffer object
+//  Return true if an error is encountered and callback returns true to skip call down chain
+//   false indicates that call down chain should proceed
+static bool PreCallValidateCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo) {
+    // TODO : Verify that renderPass FB is created with is compatible with FB
+    bool skip_call = false;
+    skip_call |= ValidateFramebufferCreateInfo(dev_data, pCreateInfo);
+    return skip_call;
+}
+
+// CreateFramebuffer state has been validated and call down chain completed so record new framebuffer object
+static void PostCallRecordCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo, VkFramebuffer fb) {
+    // Shadow create info and store in map
+    std::unique_ptr<FRAMEBUFFER_NODE> fb_node(
+        new FRAMEBUFFER_NODE(fb, pCreateInfo, dev_data->renderPassMap[pCreateInfo->renderPass]->pCreateInfo));
+
+    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
+        VkImageView view = pCreateInfo->pAttachments[i];
+        auto view_data = getImageViewData(dev_data, view);
+        if (!view_data) {
+            continue;
+        }
+        MT_FB_ATTACHMENT_INFO fb_info;
+        fb_info.mem = getImageNode(dev_data, view_data->image)->mem;
+        fb_info.image = view_data->image;
+        fb_node->attachments.push_back(fb_info);
+    }
+    dev_data->frameBufferMap[fb] = std::move(fb_node);
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
                                                  const VkAllocationCallbacks *pAllocator,
                                                  VkFramebuffer *pFramebuffer) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
-    if (VK_SUCCESS == result) {
-        // Shadow create info and store in map
-        std::lock_guard<std::mutex> lock(global_lock);
+    std::unique_lock<std::mutex> lock(global_lock);
+    bool skip_call = PreCallValidateCreateFramebuffer(dev_data, pCreateInfo);
+    lock.unlock();
 
-        auto & fbNode = dev_data->frameBufferMap[*pFramebuffer];
-        fbNode.createInfo = *pCreateInfo;
-        if (pCreateInfo->pAttachments) {
-            auto attachments = new VkImageView[pCreateInfo->attachmentCount];
-            memcpy(attachments,
-                   pCreateInfo->pAttachments,
-                   pCreateInfo->attachmentCount * sizeof(VkImageView));
-            fbNode.createInfo.pAttachments = attachments;
-        }
-        for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
-            VkImageView view = pCreateInfo->pAttachments[i];
-            auto view_data = dev_data->imageViewMap.find(view);
-            if (view_data == dev_data->imageViewMap.end()) {
-                continue;
-            }
-            MT_FB_ATTACHMENT_INFO fb_info;
-            get_mem_binding_from_object(dev_data, (uint64_t)(view_data->second.image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
-                                        &fb_info.mem);
-            fb_info.image = view_data->second.image;
-            fbNode.attachments.push_back(fb_info);
-        }
+    if (skip_call)
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+
+    VkResult result = dev_data->device_dispatch_table->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
+
+    if (VK_SUCCESS == result) {
+        lock.lock();
+        PostCallRecordCreateFramebuffer(dev_data, pCreateInfo, *pFramebuffer);
+        lock.unlock();
     }
     return result;
 }
@@ -8238,15 +8836,10 @@
         auto prev_elem = std::find(node.prev.begin(), node.prev.end(), dependent_subpasses[k]);
         auto next_elem = std::find(node.next.begin(), node.next.end(), dependent_subpasses[k]);
         if (prev_elem == node.prev.end() && next_elem == node.next.end()) {
-            // If no dependency exits an implicit dependency still might. If so, warn and if not throw an error.
+            // If no dependency exits an implicit dependency still might. If not, throw an error.
             std::unordered_set<uint32_t> processed_nodes;
-            if (FindDependency(subpass, dependent_subpasses[k], subpass_to_node, processed_nodes) ||
-                FindDependency(dependent_subpasses[k], subpass, subpass_to_node, processed_nodes)) {
-                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                     __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
-                                     "A dependency between subpasses %d and %d must exist but only an implicit one is specified.",
-                                     subpass, dependent_subpasses[k]);
-            } else {
+            if (!(FindDependency(subpass, dependent_subpasses[k], subpass_to_node, processed_nodes) ||
+                FindDependency(dependent_subpasses[k], subpass, subpass_to_node, processed_nodes))) {
                 skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
                                      __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
                                      "A dependency between subpasses %d and %d must exist but one is not specified.", subpass,
@@ -8309,7 +8902,7 @@
 static bool ValidateDependencies(const layer_data *my_data, FRAMEBUFFER_NODE const * framebuffer,
                                  RENDER_PASS_NODE const * renderPass) {
     bool skip_call = false;
-    const VkFramebufferCreateInfo *pFramebufferInfo = &framebuffer->createInfo;
+    const safe_VkFramebufferCreateInfo *pFramebufferInfo = &framebuffer->createInfo;
     const VkRenderPassCreateInfo *pCreateInfo = renderPass->pCreateInfo;
     auto const & subpass_to_node = renderPass->subpassToNode;
     std::vector<std::vector<uint32_t>> output_attachment_to_subpass(pCreateInfo->attachmentCount);
@@ -8325,25 +8918,24 @@
                 overlapping_attachments[j].push_back(i);
                 continue;
             }
-            auto view_data_i = my_data->imageViewMap.find(viewi);
-            auto view_data_j = my_data->imageViewMap.find(viewj);
-            if (view_data_i == my_data->imageViewMap.end() || view_data_j == my_data->imageViewMap.end()) {
+            auto view_data_i = getImageViewData(my_data, viewi);
+            auto view_data_j = getImageViewData(my_data, viewj);
+            if (!view_data_i || !view_data_j) {
                 continue;
             }
-            if (view_data_i->second.image == view_data_j->second.image &&
-                isRegionOverlapping(view_data_i->second.subresourceRange, view_data_j->second.subresourceRange)) {
+            if (view_data_i->image == view_data_j->image &&
+                isRegionOverlapping(view_data_i->subresourceRange, view_data_j->subresourceRange)) {
                 overlapping_attachments[i].push_back(j);
                 overlapping_attachments[j].push_back(i);
                 continue;
             }
-            auto image_data_i = my_data->imageMap.find(view_data_i->second.image);
-            auto image_data_j = my_data->imageMap.find(view_data_j->second.image);
-            if (image_data_i == my_data->imageMap.end() || image_data_j == my_data->imageMap.end()) {
+            auto image_data_i = getImageNode(my_data, view_data_i->image);
+            auto image_data_j = getImageNode(my_data, view_data_j->image);
+            if (!image_data_i || !image_data_j) {
                 continue;
             }
-            if (image_data_i->second.mem == image_data_j->second.mem &&
-                isRangeOverlapping(image_data_i->second.memOffset, image_data_i->second.memSize, image_data_j->second.memOffset,
-                                   image_data_j->second.memSize)) {
+            if (image_data_i->mem == image_data_j->mem && isRangeOverlapping(image_data_i->memOffset, image_data_i->memSize,
+                                                                             image_data_j->memOffset, image_data_j->memSize)) {
                 overlapping_attachments[i].push_back(j);
                 overlapping_attachments[j].push_back(i);
             }
@@ -8375,6 +8967,8 @@
         attachmentIndices.clear();
         for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
             uint32_t attachment = subpass.pInputAttachments[j].attachment;
+            if (attachment == VK_ATTACHMENT_UNUSED)
+                continue;
             input_attachment_to_subpass[attachment].push_back(i);
             for (auto overlapping_attachment : overlapping_attachments[attachment]) {
                 input_attachment_to_subpass[overlapping_attachment].push_back(i);
@@ -8382,6 +8976,8 @@
         }
         for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
             uint32_t attachment = subpass.pColorAttachments[j].attachment;
+            if (attachment == VK_ATTACHMENT_UNUSED)
+                continue;
             output_attachment_to_subpass[attachment].push_back(i);
             for (auto overlapping_attachment : overlapping_attachments[attachment]) {
                 output_attachment_to_subpass[overlapping_attachment].push_back(i);
@@ -8409,12 +9005,16 @@
         const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i];
         // If the attachment is an input then all subpasses that output must have a dependency relationship
         for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
-            const uint32_t &attachment = subpass.pInputAttachments[j].attachment;
+            uint32_t attachment = subpass.pInputAttachments[j].attachment;
+            if (attachment == VK_ATTACHMENT_UNUSED)
+                continue;
             CheckDependencyExists(my_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
         }
         // If the attachment is an output then all subpasses that use the attachment must have a dependency relationship
         for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
-            const uint32_t &attachment = subpass.pColorAttachments[j].attachment;
+            uint32_t attachment = subpass.pColorAttachments[j].attachment;
+            if (attachment == VK_ATTACHMENT_UNUSED)
+                continue;
             CheckDependencyExists(my_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
             CheckDependencyExists(my_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip_call);
         }
@@ -8457,63 +9057,113 @@
 static bool ValidateLayouts(const layer_data *my_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo) {
     bool skip = false;
 
+    // Track when we're observing the first use of an attachment
+    std::vector<bool> attach_first_use(pCreateInfo->attachmentCount, true);
     for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
         const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i];
-        for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
-            if (subpass.pInputAttachments[j].layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
-                subpass.pInputAttachments[j].layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
-                if (subpass.pInputAttachments[j].layout == VK_IMAGE_LAYOUT_GENERAL) {
-                    // TODO: Verify Valid Use in spec. I believe this is allowed (valid) but may not be optimal performance
-                    skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                    (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                    "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
-                } else {
-                    skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                    DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                    "Layout for input attachment is %s but can only be READ_ONLY_OPTIMAL or GENERAL.",
-                                    string_VkImageLayout(subpass.pInputAttachments[j].layout));
-                }
-            }
-            auto attach_index = subpass.pInputAttachments[j].attachment;
-            skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pInputAttachments[j].layout, attach_index,
-                                                          pCreateInfo->pAttachments[attach_index]);
-        }
         for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
-            if (subpass.pColorAttachments[j].layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
-                if (subpass.pColorAttachments[j].layout == VK_IMAGE_LAYOUT_GENERAL) {
-                    // TODO: Verify Valid Use in spec. I believe this is allowed (valid) but may not be optimal performance
-                    skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                    (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                    "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
-                } else {
-                    skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                    DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                    "Layout for color attachment is %s but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.",
-                                    string_VkImageLayout(subpass.pColorAttachments[j].layout));
-                }
-            }
             auto attach_index = subpass.pColorAttachments[j].attachment;
-            skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pColorAttachments[j].layout, attach_index,
-                                                          pCreateInfo->pAttachments[attach_index]);
-        }
-        if ((subpass.pDepthStencilAttachment != NULL) && (subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
-            if (subpass.pDepthStencilAttachment->layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
-                if (subpass.pDepthStencilAttachment->layout == VK_IMAGE_LAYOUT_GENERAL) {
-                    // TODO: Verify Valid Use in spec. I believe this is allowed (valid) but may not be optimal performance
-                    skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                    (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                    "Layout for depth attachment is GENERAL but should be DEPTH_STENCIL_ATTACHMENT_OPTIMAL.");
-                } else {
-                    skip |=
-                        log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+            if (attach_index == VK_ATTACHMENT_UNUSED)
+                continue;
+
+            switch (subpass.pColorAttachments[j].layout) {
+            case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
+                /* This is ideal. */
+                break;
+
+            case VK_IMAGE_LAYOUT_GENERAL:
+                /* May not be optimal; TODO: reconsider this warning based on
+                 * other constraints?
+                 */
+                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                                 DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                "Layout for depth attachment is %s but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL or GENERAL.",
-                                string_VkImageLayout(subpass.pDepthStencilAttachment->layout));
-                }
+                                "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
+                break;
+
+            default:
+                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                                "Layout for color attachment is %s but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.",
+                                string_VkImageLayout(subpass.pColorAttachments[j].layout));
             }
+
+            if (attach_first_use[attach_index]) {
+                skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pColorAttachments[j].layout,
+                                                              attach_index, pCreateInfo->pAttachments[attach_index]);
+            }
+            attach_first_use[attach_index] = false;
+        }
+        if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
+            switch (subpass.pDepthStencilAttachment->layout) {
+            case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
+            case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
+                /* These are ideal. */
+                break;
+
+            case VK_IMAGE_LAYOUT_GENERAL:
+                /* May not be optimal; TODO: reconsider this warning based on
+                 * other constraints? GENERAL can be better than doing a bunch
+                 * of transitions.
+                 */
+                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                                "GENERAL layout for depth attachment may not give optimal performance.");
+                break;
+
+            default:
+                /* No other layouts are acceptable */
+                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                                "Layout for depth attachment is %s but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "
+                                "DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.",
+                                string_VkImageLayout(subpass.pDepthStencilAttachment->layout));
+            }
+
             auto attach_index = subpass.pDepthStencilAttachment->attachment;
-            skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pDepthStencilAttachment->layout,
-                                                          attach_index, pCreateInfo->pAttachments[attach_index]);
+            if (attach_first_use[attach_index]) {
+                skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pDepthStencilAttachment->layout,
+                                                              attach_index, pCreateInfo->pAttachments[attach_index]);
+            }
+            attach_first_use[attach_index] = false;
+        }
+        for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
+            auto attach_index = subpass.pInputAttachments[j].attachment;
+            if (attach_index == VK_ATTACHMENT_UNUSED)
+                continue;
+
+            switch (subpass.pInputAttachments[j].layout) {
+            case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
+            case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
+                /* These are ideal. */
+                break;
+
+            case VK_IMAGE_LAYOUT_GENERAL:
+                /* May not be optimal. TODO: reconsider this warning based on
+                 * other constraints.
+                 */
+                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                                "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
+                break;
+
+            default:
+                /* No other layouts are acceptable */
+                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                                "Layout for input attachment is %s but can only be READ_ONLY_OPTIMAL or GENERAL.",
+                                string_VkImageLayout(subpass.pInputAttachments[j].layout));
+            }
+
+            if (attach_first_use[attach_index]) {
+                skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pInputAttachments[j].layout,
+                                                              attach_index, pCreateInfo->pAttachments[attach_index]);
+            }
+            attach_first_use[attach_index] = false;
         }
     }
     return skip;
@@ -8585,26 +9235,131 @@
     return res;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
-                                                const VkAllocationCallbacks *pAllocator,
-                                                VkRenderPass *pRenderPass) {
+static bool ValidateAttachmentIndex(layer_data *dev_data, uint32_t attachment, uint32_t attachment_count, const char *type) {
     bool skip_call = false;
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    // Create DAG
-    std::vector<bool> has_self_dependency(pCreateInfo->subpassCount);
-    std::vector<DAGNode> subpass_to_node(pCreateInfo->subpassCount);
-    {
-        std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= CreatePassDAG(dev_data, device, pCreateInfo, subpass_to_node, has_self_dependency);
-        // Validate
-        skip_call |= ValidateLayouts(dev_data, device, pCreateInfo);
-        if (skip_call) {
-            return VK_ERROR_VALIDATION_FAILED_EXT;
+    if (attachment >= attachment_count && attachment != VK_ATTACHMENT_UNUSED) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                             DRAWSTATE_INVALID_ATTACHMENT_INDEX, "DS",
+                             "CreateRenderPass: %s attachment %d cannot be greater than the total number of attachments %d.",
+                             type, attachment, attachment_count);
+    }
+    return skip_call;
+}
+
+static bool IsPowerOfTwo(unsigned x) {
+    return x && !(x & (x-1));
+}
+
+static bool ValidateRenderpassAttachmentUsage(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo) {
+    bool skip_call = false;
+    for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
+        const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i];
+        if (subpass.pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS) {
+            skip_call |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                        DRAWSTATE_INVALID_RENDERPASS, "DS",
+                        "CreateRenderPass: Pipeline bind point for subpass %d must be VK_PIPELINE_BIND_POINT_GRAPHICS.", i);
+        }
+        for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) {
+            uint32_t attachment = subpass.pPreserveAttachments[j];
+            if (attachment == VK_ATTACHMENT_UNUSED) {
+                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                     __LINE__, DRAWSTATE_INVALID_ATTACHMENT_INDEX, "DS",
+                                     "CreateRenderPass:  Preserve attachment (%d) must not be VK_ATTACHMENT_UNUSED.", j);
+            } else {
+                skip_call |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Preserve");
+            }
+        }
+
+        auto subpass_performs_resolve = subpass.pResolveAttachments && std::any_of(
+            subpass.pResolveAttachments, subpass.pResolveAttachments + subpass.colorAttachmentCount,
+            [](VkAttachmentReference ref) { return ref.attachment != VK_ATTACHMENT_UNUSED; });
+
+        unsigned sample_count = 0;
+
+        for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
+            uint32_t attachment;
+            if (subpass.pResolveAttachments) {
+                attachment = subpass.pResolveAttachments[j].attachment;
+                skip_call |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Resolve");
+
+                if (!skip_call && attachment != VK_ATTACHMENT_UNUSED &&
+                    pCreateInfo->pAttachments[attachment].samples != VK_SAMPLE_COUNT_1_BIT) {
+                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+                                         __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
+                                         "CreateRenderPass:  Subpass %u requests multisample resolve into attachment %u, "
+                                         "which must have VK_SAMPLE_COUNT_1_BIT but has %s",
+                                         i, attachment, string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment].samples));
+                }
+            }
+            attachment = subpass.pColorAttachments[j].attachment;
+            skip_call |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Color");
+
+            if (!skip_call && attachment != VK_ATTACHMENT_UNUSED) {
+                sample_count |= (unsigned)pCreateInfo->pAttachments[attachment].samples;
+
+                if (subpass_performs_resolve &&
+                    pCreateInfo->pAttachments[attachment].samples == VK_SAMPLE_COUNT_1_BIT) {
+                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+                                         __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
+                                         "CreateRenderPass:  Subpass %u requests multisample resolve from attachment %u "
+                                         "which has VK_SAMPLE_COUNT_1_BIT",
+                                         i, attachment);
+                }
+            }
+        }
+
+        if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
+            uint32_t attachment = subpass.pDepthStencilAttachment->attachment;
+            skip_call |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Depth stencil");
+
+            if (!skip_call && attachment != VK_ATTACHMENT_UNUSED) {
+                sample_count |= (unsigned)pCreateInfo->pAttachments[attachment].samples;
+            }
+        }
+
+        for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
+            uint32_t attachment = subpass.pInputAttachments[j].attachment;
+            skip_call |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Input");
+        }
+
+        if (sample_count && !IsPowerOfTwo(sample_count)) {
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
+                                 __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
+                                 "CreateRenderPass:  Subpass %u attempts to render to "
+                                 "attachments with inconsistent sample counts",
+                                 i);
         }
     }
+    return skip_call;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
+                                                const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
+    bool skip_call = false;
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
+    std::unique_lock<std::mutex> lock(global_lock);
+
+    skip_call |= ValidateLayouts(dev_data, device, pCreateInfo);
+    // TODO: As part of wrapping up the mem_tracker/core_validation merge the following routine should be consolidated with
+    //       ValidateLayouts.
+    skip_call |= ValidateRenderpassAttachmentUsage(dev_data, pCreateInfo);
+    lock.unlock();
+
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+
     VkResult result = dev_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
+
     if (VK_SUCCESS == result) {
-        // TODOSC : Merge in tracking of renderpass from shader_checker
+        lock.lock();
+
+        std::vector<bool> has_self_dependency(pCreateInfo->subpassCount);
+        std::vector<DAGNode> subpass_to_node(pCreateInfo->subpassCount);
+        skip_call |= CreatePassDAG(dev_data, device, pCreateInfo, subpass_to_node, has_self_dependency);
+
         // Shadow create info and store in map
         VkRenderPassCreateInfo *localRPCI = new VkRenderPassCreateInfo(*pCreateInfo);
         if (pCreateInfo->pAttachments) {
@@ -8664,97 +9419,48 @@
             MT_PASS_ATTACHMENT_INFO pass_info;
             pass_info.load_op = desc.loadOp;
             pass_info.store_op = desc.storeOp;
+            pass_info.stencil_load_op = desc.stencilLoadOp;
+            pass_info.stencil_store_op = desc.stencilStoreOp;
             pass_info.attachment = i;
             render_pass->attachments.push_back(pass_info);
         }
         // TODO: Maybe fill list and then copy instead of locking
         std::unordered_map<uint32_t, bool> &attachment_first_read = render_pass->attachment_first_read;
-        std::unordered_map<uint32_t, VkImageLayout> &attachment_first_layout =
-            render_pass->attachment_first_layout;
+        std::unordered_map<uint32_t, VkImageLayout> &attachment_first_layout = render_pass->attachment_first_layout;
         for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
             const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i];
-            if (subpass.pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS) {
-                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                     __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
-                                     "Pipeline bind point for subpass %d must be VK_PIPELINE_BIND_POINT_GRAPHICS.", i);
-            }
-            for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) {
-                uint32_t attachment = subpass.pPreserveAttachments[j];
-                if (attachment >= pCreateInfo->attachmentCount) {
-                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                         __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
-                                         "Preserve attachment %d cannot be greater than the total number of attachments %d.",
-                                         attachment, pCreateInfo->attachmentCount);
-                }
-            }
             for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
-                uint32_t attachment;
-                if (subpass.pResolveAttachments) {
-                    attachment = subpass.pResolveAttachments[j].attachment;
-                    if (attachment >= pCreateInfo->attachmentCount && attachment != VK_ATTACHMENT_UNUSED) {
-                        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                             __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
-                                             "Color attachment %d cannot be greater than the total number of attachments %d.",
-                                             attachment, pCreateInfo->attachmentCount);
-                        continue;
-                    }
+                uint32_t attachment = subpass.pColorAttachments[j].attachment;
+                if (!attachment_first_read.count(attachment)) {
+                    attachment_first_read.insert(std::make_pair(attachment, false));
+                    attachment_first_layout.insert(std::make_pair(attachment, subpass.pColorAttachments[j].layout));
                 }
-                attachment = subpass.pColorAttachments[j].attachment;
-                if (attachment >= pCreateInfo->attachmentCount) {
-                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                         __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
-                                         "Color attachment %d cannot be greater than the total number of attachments %d.",
-                                         attachment, pCreateInfo->attachmentCount);
-                    continue;
-                }
-                if (attachment_first_read.count(attachment))
-                    continue;
-                attachment_first_read.insert(std::make_pair(attachment, false));
-                attachment_first_layout.insert(std::make_pair(attachment, subpass.pColorAttachments[j].layout));
             }
             if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
                 uint32_t attachment = subpass.pDepthStencilAttachment->attachment;
-                if (attachment >= pCreateInfo->attachmentCount) {
-                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                         __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
-                                         "Depth stencil attachment %d cannot be greater than the total number of attachments %d.",
-                                         attachment, pCreateInfo->attachmentCount);
-                    continue;
+                if (!attachment_first_read.count(attachment)) {
+                    attachment_first_read.insert(std::make_pair(attachment, false));
+                    attachment_first_layout.insert(std::make_pair(attachment, subpass.pDepthStencilAttachment->layout));
                 }
-                if (attachment_first_read.count(attachment))
-                    continue;
-                attachment_first_read.insert(std::make_pair(attachment, false));
-                attachment_first_layout.insert(std::make_pair(attachment, subpass.pDepthStencilAttachment->layout));
             }
             for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
                 uint32_t attachment = subpass.pInputAttachments[j].attachment;
-                if (attachment >= pCreateInfo->attachmentCount) {
-                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                         __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
-                                         "Input attachment %d cannot be greater than the total number of attachments %d.",
-                                         attachment, pCreateInfo->attachmentCount);
-                    continue;
+                if (!attachment_first_read.count(attachment)) {
+                    attachment_first_read.insert(std::make_pair(attachment, true));
+                    attachment_first_layout.insert(std::make_pair(attachment, subpass.pInputAttachments[j].layout));
                 }
-                if (attachment_first_read.count(attachment))
-                    continue;
-                attachment_first_read.insert(std::make_pair(attachment, true));
-                attachment_first_layout.insert(std::make_pair(attachment, subpass.pInputAttachments[j].layout));
             }
         }
 #endif
-        {
-            std::lock_guard<std::mutex> lock(global_lock);
-            dev_data->renderPassMap[*pRenderPass] = render_pass;
-        }
+        dev_data->renderPassMap[*pRenderPass] = render_pass;
     }
     return result;
 }
+
 // Free the renderpass shadow
 static void deleteRenderPasses(layer_data *my_data) {
-    if (my_data->renderPassMap.size() <= 0)
-        return;
-    for (auto ii = my_data->renderPassMap.begin(); ii != my_data->renderPassMap.end(); ++ii) {
-        const VkRenderPassCreateInfo *pRenderPassInfo = (*ii).second->pCreateInfo;
+    for (auto renderPass : my_data->renderPassMap) {
+        const VkRenderPassCreateInfo *pRenderPassInfo = renderPass.second->pCreateInfo;
         delete[] pRenderPassInfo->pAttachments;
         if (pRenderPassInfo->pSubpasses) {
             for (uint32_t i = 0; i < pRenderPassInfo->subpassCount; ++i) {
@@ -8774,7 +9480,7 @@
         }
         delete[] pRenderPassInfo->pDependencies;
         delete pRenderPassInfo;
-        delete (*ii).second;
+        delete renderPass.second;
     }
     my_data->renderPassMap.clear();
 }
@@ -8782,7 +9488,7 @@
 static bool VerifyFramebufferAndRenderPassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin) {
     bool skip_call = false;
     const VkRenderPassCreateInfo *pRenderPassInfo = dev_data->renderPassMap[pRenderPassBegin->renderPass]->pCreateInfo;
-    const VkFramebufferCreateInfo framebufferInfo = dev_data->frameBufferMap[pRenderPassBegin->framebuffer].createInfo;
+    const safe_VkFramebufferCreateInfo framebufferInfo = dev_data->frameBufferMap[pRenderPassBegin->framebuffer]->createInfo;
     if (pRenderPassInfo->attachmentCount != framebufferInfo.attachmentCount) {
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                              DRAWSTATE_INVALID_RENDERPASS, "DS", "You cannot start a render pass using a framebuffer "
@@ -8790,10 +9496,10 @@
     }
     for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) {
         const VkImageView &image_view = framebufferInfo.pAttachments[i];
-        auto image_data = dev_data->imageViewMap.find(image_view);
-        assert(image_data != dev_data->imageViewMap.end());
-        const VkImage &image = image_data->second.image;
-        const VkImageSubresourceRange &subRange = image_data->second.subresourceRange;
+        auto image_data = getImageViewData(dev_data, image_view);
+        assert(image_data);
+        const VkImage &image = image_data->image;
+        const VkImageSubresourceRange &subRange = image_data->subresourceRange;
         IMAGE_CMD_BUF_LAYOUT_NODE newNode = {pRenderPassInfo->pAttachments[i].initialLayout,
                                              pRenderPassInfo->pAttachments[i].initialLayout};
         // TODO: Do not iterate over every possibility - consolidate where possible
@@ -8807,13 +9513,16 @@
                     SetLayout(pCB, image, sub, newNode);
                     continue;
                 }
-                if (newNode.layout != node.layout) {
+                if (newNode.layout != VK_IMAGE_LAYOUT_UNDEFINED &&
+                    newNode.layout != node.layout) {
                     skip_call |=
                         log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_INVALID_RENDERPASS, "DS", "You cannot start a render pass using attachment %i "
-                                                                    "where the "
-                                                                    "initial layout is %s and the layout of the attachment at the "
-                                                                    "start of the render pass is %s. The layouts must match.",
+                                DRAWSTATE_INVALID_RENDERPASS, "DS",
+                                "You cannot start a render pass using attachment %u "
+                                "where the render pass initial layout is %s and the previous "
+                                "known layout of the attachment is %s. The layouts must match, or "
+                                "the render pass initial layout for the attachment must be "
+                                "VK_IMAGE_LAYOUT_UNDEFINED",
                                 i, string_VkImageLayout(newNode.layout), string_VkImageLayout(node.layout));
                 }
             }
@@ -8822,6 +9531,16 @@
     return skip_call;
 }
 
+static void TransitionAttachmentRefLayout(layer_data *dev_data, GLOBAL_CB_NODE *pCB,
+                                          FRAMEBUFFER_NODE *pFramebuffer,
+                                          VkAttachmentReference ref)
+{
+    if (ref.attachment != VK_ATTACHMENT_UNUSED) {
+        auto image_view = pFramebuffer->createInfo.pAttachments[ref.attachment];
+        SetLayout(dev_data, pCB, image_view, ref.layout);
+    }
+}
+
 static void TransitionSubpassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin,
                                      const int subpass_index) {
     auto renderPass = getRenderPass(dev_data, pRenderPassBegin->renderPass);
@@ -8832,19 +9551,15 @@
     if (!framebuffer)
         return;
 
-    const VkFramebufferCreateInfo &framebufferInfo = framebuffer->createInfo;
     const VkSubpassDescription &subpass = renderPass->pCreateInfo->pSubpasses[subpass_index];
     for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
-        const VkImageView &image_view = framebufferInfo.pAttachments[subpass.pInputAttachments[j].attachment];
-        SetLayout(dev_data, pCB, image_view, subpass.pInputAttachments[j].layout);
+        TransitionAttachmentRefLayout(dev_data, pCB, framebuffer, subpass.pInputAttachments[j]);
     }
     for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
-        const VkImageView &image_view = framebufferInfo.pAttachments[subpass.pColorAttachments[j].attachment];
-        SetLayout(dev_data, pCB, image_view, subpass.pColorAttachments[j].layout);
+        TransitionAttachmentRefLayout(dev_data, pCB, framebuffer, subpass.pColorAttachments[j]);
     }
-    if ((subpass.pDepthStencilAttachment != NULL) && (subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
-        const VkImageView &image_view = framebufferInfo.pAttachments[subpass.pDepthStencilAttachment->attachment];
-        SetLayout(dev_data, pCB, image_view, subpass.pDepthStencilAttachment->layout);
+    if (subpass.pDepthStencilAttachment) {
+        TransitionAttachmentRefLayout(dev_data, pCB, framebuffer, *subpass.pDepthStencilAttachment);
     }
 }
 
@@ -8869,14 +9584,14 @@
         return;
 
     for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) {
-        const VkImageView &image_view = framebuffer->createInfo.pAttachments[i];
+        auto image_view = framebuffer->createInfo.pAttachments[i];
         SetLayout(dev_data, pCB, image_view, pRenderPassInfo->pAttachments[i].finalLayout);
     }
 }
 
 static bool VerifyRenderAreaBounds(const layer_data *my_data, const VkRenderPassBeginInfo *pRenderPassBegin) {
     bool skip_call = false;
-    const VkFramebufferCreateInfo *pFramebufferInfo = &my_data->frameBufferMap.at(pRenderPassBegin->framebuffer).createInfo;
+    const safe_VkFramebufferCreateInfo *pFramebufferInfo = &getFramebuffer(my_data, pRenderPassBegin->framebuffer)->createInfo;
     if (pRenderPassBegin->renderArea.offset.x < 0 ||
         (pRenderPassBegin->renderArea.offset.x + pRenderPassBegin->renderArea.extent.width) > pFramebufferInfo->width ||
         pRenderPassBegin->renderArea.offset.y < 0 ||
@@ -8893,9 +9608,23 @@
     return skip_call;
 }
 
+// If this is a stencil format, make sure the stencil[Load|Store]Op flag is checked, while if it is a depth/color attachment the
+// [load|store]Op flag must be checked
+// TODO: The memory valid flag in DEVICE_MEM_INFO should probably be split to track the validity of stencil memory separately.
+template <typename T> static bool FormatSpecificLoadAndStoreOpSettings(VkFormat format, T color_depth_op, T stencil_op, T op) {
+    if (color_depth_op != op && stencil_op != op) {
+        return false;
+    }
+    bool check_color_depth_load_op = !vk_format_is_stencil_only(format);
+    bool check_stencil_load_op = vk_format_is_depth_and_stencil(format) || !check_color_depth_load_op;
+
+    return (((check_color_depth_load_op == true) && (color_depth_op == op)) ||
+            ((check_stencil_load_op == true) && (stencil_op == op)));
+}
+
 VKAPI_ATTR void VKAPI_CALL
 CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
@@ -8903,23 +9632,31 @@
     auto framebuffer = pRenderPassBegin ? getFramebuffer(dev_data, pRenderPassBegin->framebuffer) : nullptr;
     if (pCB) {
         if (renderPass) {
-#if MTMERGE
+            uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
             pCB->activeFramebuffer = pRenderPassBegin->framebuffer;
             for (size_t i = 0; i < renderPass->attachments.size(); ++i) {
                 MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
-                if (renderPass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+                VkFormat format = renderPass->pCreateInfo->pAttachments[renderPass->attachments[i].attachment].format;
+                if (FormatSpecificLoadAndStoreOpSettings(format, renderPass->attachments[i].load_op,
+                                                         renderPass->attachments[i].stencil_load_op,
+                                                         VK_ATTACHMENT_LOAD_OP_CLEAR)) {
+                    clear_op_size = static_cast<uint32_t>(i) + 1;
                     std::function<bool()> function = [=]() {
                         set_memory_valid(dev_data, fb_info.mem, true, fb_info.image);
                         return false;
                     };
                     pCB->validate_functions.push_back(function);
-                } else if (renderPass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) {
+                } else if (FormatSpecificLoadAndStoreOpSettings(format, renderPass->attachments[i].load_op,
+                                                                renderPass->attachments[i].stencil_load_op,
+                                                                VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
                     std::function<bool()> function = [=]() {
                         set_memory_valid(dev_data, fb_info.mem, false, fb_info.image);
                         return false;
                     };
                     pCB->validate_functions.push_back(function);
-                } else if (renderPass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_LOAD) {
+                } else if (FormatSpecificLoadAndStoreOpSettings(format, renderPass->attachments[i].load_op,
+                                                                renderPass->attachments[i].stencil_load_op,
+                                                                VK_ATTACHMENT_LOAD_OP_LOAD)) {
                     std::function<bool()> function = [=]() {
                         return validate_memory_is_valid(dev_data, fb_info.mem, "vkCmdBeginRenderPass()", fb_info.image);
                     };
@@ -8932,55 +9669,68 @@
                     pCB->validate_functions.push_back(function);
                 }
             }
-#endif
-            skipCall |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin);
-            skipCall |= VerifyFramebufferAndRenderPassLayouts(dev_data, pCB, pRenderPassBegin);
-            skipCall |= insideRenderPass(dev_data, pCB, "vkCmdBeginRenderPass");
-            if (renderPass) {
-                skipCall |= ValidateDependencies(dev_data, framebuffer, renderPass);
+            if (clear_op_size > pRenderPassBegin->clearValueCount) {
+                skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                            reinterpret_cast<uint64_t &>(renderPass), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
+                            "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there must "
+                            "be at least %u "
+                            "entries in pClearValues array to account for the highest index attachment in renderPass 0x%" PRIx64
+                            " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array "
+                            "is indexed by attachment number so even if some pClearValues entries between 0 and %u correspond to "
+                            "attachments that aren't cleared they will be ignored.",
+                            pRenderPassBegin->clearValueCount, clear_op_size, reinterpret_cast<uint64_t &>(renderPass),
+                            clear_op_size, clear_op_size - 1);
             }
+            skip_call |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin);
+            skip_call |= VerifyFramebufferAndRenderPassLayouts(dev_data, pCB, pRenderPassBegin);
+            skip_call |= insideRenderPass(dev_data, pCB, "vkCmdBeginRenderPass");
+            skip_call |= ValidateDependencies(dev_data, framebuffer, renderPass);
+            skip_call |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdBeginRenderPass");
+            skip_call |= addCmd(dev_data, pCB, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()");
             pCB->activeRenderPass = renderPass;
-            skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdBeginRenderPass");
-            skipCall |= addCmd(dev_data, pCB, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()");
             // This is a shallow copy as that is all that is needed for now
             pCB->activeRenderPassBeginInfo = *pRenderPassBegin;
             pCB->activeSubpass = 0;
             pCB->activeSubpassContents = contents;
             pCB->framebuffers.insert(pRenderPassBegin->framebuffer);
             // Connect this framebuffer to this cmdBuffer
-            framebuffer->referencingCmdBuffers.insert(pCB->commandBuffer);
+            framebuffer->cb_bindings.insert(pCB);
+
+            // transition attachments to the correct layouts for the first subpass
+            TransitionSubpassLayouts(dev_data, pCB, &pCB->activeRenderPassBeginInfo, pCB->activeSubpass);
         } else {
-            skipCall |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_INVALID_RENDERPASS, "DS", "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
+            skip_call |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                        DRAWSTATE_INVALID_RENDERPASS, "DS", "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
         }
     }
     lock.unlock();
-    if (!skipCall) {
+    if (!skip_call) {
         dev_data->device_dispatch_table->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
     }
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdNextSubpass");
-        skipCall |= addCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()");
+        skip_call |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdNextSubpass");
+        skip_call |= addCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()");
         pCB->activeSubpass++;
         pCB->activeSubpassContents = contents;
         TransitionSubpassLayouts(dev_data, pCB, &pCB->activeRenderPassBeginInfo, pCB->activeSubpass);
-        skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass");
+        skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass");
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdNextSubpass(commandBuffer, contents);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     auto pCB = getCBNode(dev_data, commandBuffer);
@@ -8990,13 +9740,17 @@
         if (pRPNode) {
             for (size_t i = 0; i < pRPNode->attachments.size(); ++i) {
                 MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
-                if (pRPNode->attachments[i].store_op == VK_ATTACHMENT_STORE_OP_STORE) {
+                VkFormat format = pRPNode->pCreateInfo->pAttachments[pRPNode->attachments[i].attachment].format;
+                if (FormatSpecificLoadAndStoreOpSettings(format, pRPNode->attachments[i].store_op,
+                                                         pRPNode->attachments[i].stencil_store_op, VK_ATTACHMENT_STORE_OP_STORE)) {
                     std::function<bool()> function = [=]() {
                         set_memory_valid(dev_data, fb_info.mem, true, fb_info.image);
                         return false;
                     };
                     pCB->validate_functions.push_back(function);
-                } else if (pRPNode->attachments[i].store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE) {
+                } else if (FormatSpecificLoadAndStoreOpSettings(format, pRPNode->attachments[i].store_op,
+                                                                pRPNode->attachments[i].stencil_store_op,
+                                                                VK_ATTACHMENT_STORE_OP_DONT_CARE)) {
                     std::function<bool()> function = [=]() {
                         set_memory_valid(dev_data, fb_info.mem, false, fb_info.image);
                         return false;
@@ -9005,79 +9759,74 @@
                 }
             }
         }
-        skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdEndRenderpass");
-        skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdEndRenderPass");
-        skipCall |= addCmd(dev_data, pCB, CMD_ENDRENDERPASS, "vkCmdEndRenderPass()");
+        skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdEndRenderpass");
+        skip_call |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdEndRenderPass");
+        skip_call |= addCmd(dev_data, pCB, CMD_ENDRENDERPASS, "vkCmdEndRenderPass()");
         TransitionFinalSubpassLayouts(dev_data, pCB, &pCB->activeRenderPassBeginInfo);
         pCB->activeRenderPass = nullptr;
         pCB->activeSubpass = 0;
         pCB->activeFramebuffer = VK_NULL_HANDLE;
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdEndRenderPass(commandBuffer);
 }
 
-static bool logInvalidAttachmentMessage(layer_data *dev_data, VkCommandBuffer secondaryBuffer, RENDER_PASS_NODE const *secondaryPass,
-                                        RENDER_PASS_NODE const *primaryPass, uint32_t primaryAttach, uint32_t secondaryAttach,
-                                        const char *msg) {
+static bool logInvalidAttachmentMessage(layer_data *dev_data, VkCommandBuffer secondaryBuffer, uint32_t primaryAttach,
+                                        uint32_t secondaryAttach, const char *msg) {
     return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                    DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
-                   "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p which has a render pass 0x%" PRIx64
-                   " that is not compatible with the current render pass 0x%" PRIx64 "."
-                   "Attachment %" PRIu32 " is not compatible with %" PRIu32 ". %s",
-                   (void *)secondaryBuffer, (uint64_t)(secondaryPass->renderPass), (uint64_t)(primaryPass->renderPass), primaryAttach, secondaryAttach,
-                   msg);
+                   "vkCmdExecuteCommands() called w/ invalid Secondary Cmd Buffer 0x%" PRIx64 " which has a render pass "
+                   "that is not compatible with the Primary Cmd Buffer current render pass. "
+                   "Attachment %u is not compatible with %u: %s",
+                   reinterpret_cast<uint64_t &>(secondaryBuffer), primaryAttach, secondaryAttach, msg);
 }
 
-static bool validateAttachmentCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer, RENDER_PASS_NODE const *primaryPass,
-                                            uint32_t primaryAttach, VkCommandBuffer secondaryBuffer, RENDER_PASS_NODE const *secondaryPass,
+static bool validateAttachmentCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer,
+                                            VkRenderPassCreateInfo const *primaryPassCI, uint32_t primaryAttach,
+                                            VkCommandBuffer secondaryBuffer, VkRenderPassCreateInfo const *secondaryPassCI,
                                             uint32_t secondaryAttach, bool is_multi) {
     bool skip_call = false;
-    if (primaryPass->pCreateInfo->attachmentCount <= primaryAttach) {
+    if (primaryPassCI->attachmentCount <= primaryAttach) {
         primaryAttach = VK_ATTACHMENT_UNUSED;
     }
-    if (secondaryPass->pCreateInfo->attachmentCount <= secondaryAttach) {
+    if (secondaryPassCI->attachmentCount <= secondaryAttach) {
         secondaryAttach = VK_ATTACHMENT_UNUSED;
     }
     if (primaryAttach == VK_ATTACHMENT_UNUSED && secondaryAttach == VK_ATTACHMENT_UNUSED) {
         return skip_call;
     }
     if (primaryAttach == VK_ATTACHMENT_UNUSED) {
-        skip_call |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, secondaryPass, primaryPass, primaryAttach,
-                                                 secondaryAttach, "The first is unused while the second is not.");
+        skip_call |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach,
+                                                 "The first is unused while the second is not.");
         return skip_call;
     }
     if (secondaryAttach == VK_ATTACHMENT_UNUSED) {
-        skip_call |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, secondaryPass, primaryPass, primaryAttach,
-                                                 secondaryAttach, "The second is unused while the first is not.");
+        skip_call |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach,
+                                                 "The second is unused while the first is not.");
         return skip_call;
     }
-    if (primaryPass->pCreateInfo->pAttachments[primaryAttach].format !=
-        secondaryPass->pCreateInfo->pAttachments[secondaryAttach].format) {
-        skip_call |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, secondaryPass, primaryPass, primaryAttach,
-                                                 secondaryAttach, "They have different formats.");
+    if (primaryPassCI->pAttachments[primaryAttach].format != secondaryPassCI->pAttachments[secondaryAttach].format) {
+        skip_call |=
+            logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach, "They have different formats.");
     }
-    if (primaryPass->pCreateInfo->pAttachments[primaryAttach].samples !=
-        secondaryPass->pCreateInfo->pAttachments[secondaryAttach].samples) {
-        skip_call |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, secondaryPass, primaryPass, primaryAttach,
-                                                 secondaryAttach, "They have different samples.");
+    if (primaryPassCI->pAttachments[primaryAttach].samples != secondaryPassCI->pAttachments[secondaryAttach].samples) {
+        skip_call |=
+            logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach, "They have different samples.");
     }
-    if (is_multi &&
-        primaryPass->pCreateInfo->pAttachments[primaryAttach].flags !=
-            secondaryPass->pCreateInfo->pAttachments[secondaryAttach].flags) {
-        skip_call |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, secondaryPass, primaryPass, primaryAttach,
-                                                 secondaryAttach, "They have different flags.");
+    if (is_multi && primaryPassCI->pAttachments[primaryAttach].flags != secondaryPassCI->pAttachments[secondaryAttach].flags) {
+        skip_call |=
+            logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach, "They have different flags.");
     }
     return skip_call;
 }
 
-static bool validateSubpassCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer, RENDER_PASS_NODE const *primaryPass,
-                                         VkCommandBuffer secondaryBuffer, RENDER_PASS_NODE const *secondaryPass, const int subpass,
-                                         bool is_multi) {
+static bool validateSubpassCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer,
+                                         VkRenderPassCreateInfo const *primaryPassCI, VkCommandBuffer secondaryBuffer,
+                                         VkRenderPassCreateInfo const *secondaryPassCI, const int subpass, bool is_multi) {
     bool skip_call = false;
-    const VkSubpassDescription &primary_desc = primaryPass->pCreateInfo->pSubpasses[subpass];
-    const VkSubpassDescription &secondary_desc = secondaryPass->pCreateInfo->pSubpasses[subpass];
+    const VkSubpassDescription &primary_desc = primaryPassCI->pSubpasses[subpass];
+    const VkSubpassDescription &secondary_desc = secondaryPassCI->pSubpasses[subpass];
     uint32_t maxInputAttachmentCount = std::max(primary_desc.inputAttachmentCount, secondary_desc.inputAttachmentCount);
     for (uint32_t i = 0; i < maxInputAttachmentCount; ++i) {
         uint32_t primary_input_attach = VK_ATTACHMENT_UNUSED, secondary_input_attach = VK_ATTACHMENT_UNUSED;
@@ -9087,8 +9836,8 @@
         if (i < secondary_desc.inputAttachmentCount) {
             secondary_input_attach = secondary_desc.pInputAttachments[i].attachment;
         }
-        skip_call |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPass, primary_input_attach, secondaryBuffer,
-                                                     secondaryPass, secondary_input_attach, is_multi);
+        skip_call |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPassCI, primary_input_attach, secondaryBuffer,
+                                                     secondaryPassCI, secondary_input_attach, is_multi);
     }
     uint32_t maxColorAttachmentCount = std::max(primary_desc.colorAttachmentCount, secondary_desc.colorAttachmentCount);
     for (uint32_t i = 0; i < maxColorAttachmentCount; ++i) {
@@ -9099,8 +9848,8 @@
         if (i < secondary_desc.colorAttachmentCount) {
             secondary_color_attach = secondary_desc.pColorAttachments[i].attachment;
         }
-        skip_call |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPass, primary_color_attach, secondaryBuffer,
-                                                     secondaryPass, secondary_color_attach, is_multi);
+        skip_call |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPassCI, primary_color_attach, secondaryBuffer,
+                                                     secondaryPassCI, secondary_color_attach, is_multi);
         uint32_t primary_resolve_attach = VK_ATTACHMENT_UNUSED, secondary_resolve_attach = VK_ATTACHMENT_UNUSED;
         if (i < primary_desc.colorAttachmentCount && primary_desc.pResolveAttachments) {
             primary_resolve_attach = primary_desc.pResolveAttachments[i].attachment;
@@ -9108,8 +9857,8 @@
         if (i < secondary_desc.colorAttachmentCount && secondary_desc.pResolveAttachments) {
             secondary_resolve_attach = secondary_desc.pResolveAttachments[i].attachment;
         }
-        skip_call |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPass, primary_resolve_attach, secondaryBuffer,
-                                                     secondaryPass, secondary_resolve_attach, is_multi);
+        skip_call |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPassCI, primary_resolve_attach,
+                                                     secondaryBuffer, secondaryPassCI, secondary_resolve_attach, is_multi);
     }
     uint32_t primary_depthstencil_attach = VK_ATTACHMENT_UNUSED, secondary_depthstencil_attach = VK_ATTACHMENT_UNUSED;
     if (primary_desc.pDepthStencilAttachment) {
@@ -9118,48 +9867,32 @@
     if (secondary_desc.pDepthStencilAttachment) {
         secondary_depthstencil_attach = secondary_desc.pDepthStencilAttachment[0].attachment;
     }
-    skip_call |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPass, primary_depthstencil_attach, secondaryBuffer,
-                                                 secondaryPass, secondary_depthstencil_attach, is_multi);
+    skip_call |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPassCI, primary_depthstencil_attach,
+                                                 secondaryBuffer, secondaryPassCI, secondary_depthstencil_attach, is_multi);
     return skip_call;
 }
 
-static bool validateRenderPassCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer, VkRenderPass primaryPass,
-                                            VkCommandBuffer secondaryBuffer, VkRenderPass secondaryPass) {
+// Verify that given renderPass CreateInfo for primary and secondary command buffers are compatible.
+//  This function deals directly with the CreateInfo, there are overloaded versions below that can take the renderPass handle and
+//  will then feed into this function
+static bool validateRenderPassCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer,
+                                            VkRenderPassCreateInfo const *primaryPassCI, VkCommandBuffer secondaryBuffer,
+                                            VkRenderPassCreateInfo const *secondaryPassCI) {
     bool skip_call = false;
-    // Early exit if renderPass objects are identical (and therefore compatible)
-    if (primaryPass == secondaryPass)
-        return skip_call;
-    auto primary_render_pass = getRenderPass(dev_data, primaryPass);
-    auto secondary_render_pass = getRenderPass(dev_data, secondaryPass);
-    if (!primary_render_pass) {
-        skip_call |=
-            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                    DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
-                    "vkCmdExecuteCommands() called w/ invalid current Cmd Buffer 0x%p which has invalid render pass 0x%" PRIx64 ".",
-                    (void *)primaryBuffer, (uint64_t)(primaryPass));
-        return skip_call;
-    }
-    if (!secondary_render_pass) {
-        skip_call |=
-            log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                    DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
-                    "vkCmdExecuteCommands() called w/ invalid secondary Cmd Buffer 0x%p which has invalid render pass 0x%" PRIx64 ".",
-                    (void *)secondaryBuffer, (uint64_t)(secondaryPass));
-        return skip_call;
-    }
-    if (primary_render_pass->pCreateInfo->subpassCount != secondary_render_pass->pCreateInfo->subpassCount) {
+
+    if (primaryPassCI->subpassCount != secondaryPassCI->subpassCount) {
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                              DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
-                             "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p which has a render pass 0x%" PRIx64
-                             " that is not compatible with the current render pass 0x%" PRIx64 "."
-                             "They have a different number of subpasses.",
-                             (void *)secondaryBuffer, (uint64_t)(secondaryPass), (uint64_t)(primaryPass));
-        return skip_call;
-    }
-    auto subpassCount = primary_render_pass->pCreateInfo->subpassCount;
-    for (uint32_t i = 0; i < subpassCount; ++i) {
-        skip_call |= validateSubpassCompatibility(dev_data, primaryBuffer, primary_render_pass, secondaryBuffer,
-                                                  secondary_render_pass, i, subpassCount > 1);
+                             "vkCmdExecuteCommands() called w/ invalid secondary Cmd Buffer 0x%" PRIx64
+                             " that has a subpassCount of %u that is incompatible with the primary Cmd Buffer 0x%" PRIx64
+                             " that has a subpassCount of %u.",
+                             reinterpret_cast<uint64_t &>(secondaryBuffer), secondaryPassCI->subpassCount,
+                             reinterpret_cast<uint64_t &>(primaryBuffer), primaryPassCI->subpassCount);
+    } else {
+        for (uint32_t i = 0; i < primaryPassCI->subpassCount; ++i) {
+            skip_call |= validateSubpassCompatibility(dev_data, primaryBuffer, primaryPassCI, secondaryBuffer, secondaryPassCI, i,
+                                                      primaryPassCI->subpassCount > 1);
+        }
     }
     return skip_call;
 }
@@ -9175,10 +9908,12 @@
     if (secondary_fb != VK_NULL_HANDLE) {
         if (primary_fb != secondary_fb) {
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                 DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
-                                 "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p which has a framebuffer 0x%" PRIx64
-                                 " that is not compatible with the current framebuffer 0x%" PRIx64 ".",
-                                 (void *)secondaryBuffer, (uint64_t)(secondary_fb), (uint64_t)(primary_fb));
+                                 DRAWSTATE_FRAMEBUFFER_INCOMPATIBLE, "DS",
+                                 "vkCmdExecuteCommands() called w/ invalid secondary Cmd Buffer 0x%" PRIx64
+                                 " which has a framebuffer 0x%" PRIx64
+                                 " that is not the same as the primaryCB's current active framebuffer 0x%" PRIx64 ".",
+                                 reinterpret_cast<uint64_t &>(secondaryBuffer), reinterpret_cast<uint64_t &>(secondary_fb),
+                                 reinterpret_cast<uint64_t &>(primary_fb));
         }
         auto fb = getFramebuffer(dev_data, secondary_fb);
         if (!fb) {
@@ -9189,14 +9924,17 @@
                         (void *)secondaryBuffer, (uint64_t)(secondary_fb));
             return skip_call;
         }
-        skip_call |= validateRenderPassCompatibility(dev_data, secondaryBuffer, fb->createInfo.renderPass,
-                                                     secondaryBuffer, pSubCB->beginInfo.pInheritanceInfo->renderPass);
+        auto cb_renderpass = getRenderPass(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass);
+        if (cb_renderpass->renderPass != fb->createInfo.renderPass) {
+            skip_call |= validateRenderPassCompatibility(dev_data, secondaryBuffer, fb->renderPassCreateInfo.ptr(), secondaryBuffer,
+                                                         cb_renderpass->pCreateInfo);
+        }
     }
     return skip_call;
 }
 
 static bool validateSecondaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB, GLOBAL_CB_NODE *pSubCB) {
-    bool skipCall = false;
+    bool skip_call = false;
     unordered_set<int> activeTypes;
     for (auto queryObject : pCB->activeQueries) {
         auto queryPoolData = dev_data->queryPoolMap.find(queryObject.pool);
@@ -9205,7 +9943,7 @@
                 pSubCB->beginInfo.pInheritanceInfo) {
                 VkQueryPipelineStatisticFlags cmdBufStatistics = pSubCB->beginInfo.pInheritanceInfo->pipelineStatistics;
                 if ((cmdBufStatistics & queryPoolData->second.createInfo.pipelineStatistics) != cmdBufStatistics) {
-                    skipCall |= log_msg(
+                    skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
                         "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p "
@@ -9220,7 +9958,7 @@
     for (auto queryObject : pSubCB->startedQueries) {
         auto queryPoolData = dev_data->queryPoolMap.find(queryObject.pool);
         if (queryPoolData != dev_data->queryPoolMap.end() && activeTypes.count(queryPoolData->second.createInfo.queryType)) {
-            skipCall |=
+            skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
                         "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p "
@@ -9230,12 +9968,24 @@
                         queryPoolData->second.createInfo.queryType, reinterpret_cast<void *>(pSubCB->commandBuffer));
         }
     }
-    return skipCall;
+
+    auto primary_pool = getCommandPoolNode(dev_data, pCB->createInfo.commandPool);
+    auto secondary_pool = getCommandPoolNode(dev_data, pSubCB->createInfo.commandPool);
+    if (primary_pool && secondary_pool && (primary_pool->queueFamilyIndex != secondary_pool->queueFamilyIndex)) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                             reinterpret_cast<uint64_t>(pSubCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUEUE_FAMILY, "DS",
+                             "vkCmdExecuteCommands(): Primary command buffer 0x%" PRIxLEAST64
+                             " created in queue family %d has secondary command buffer 0x%" PRIxLEAST64 " created in queue family %d.",
+                             reinterpret_cast<uint64_t>(pCB->commandBuffer), primary_pool->queueFamilyIndex,
+                             reinterpret_cast<uint64_t>(pSubCB->commandBuffer), secondary_pool->queueFamilyIndex);
+    }
+
+    return skip_call;
 }
 
 VKAPI_ATTR void VKAPI_CALL
 CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, const VkCommandBuffer *pCommandBuffers) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
@@ -9244,20 +9994,21 @@
         for (uint32_t i = 0; i < commandBuffersCount; i++) {
             pSubCB = getCBNode(dev_data, pCommandBuffers[i]);
             if (!pSubCB) {
-                skipCall |=
+                skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                             DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
                             "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p in element %u of pCommandBuffers array.",
                             (void *)pCommandBuffers[i], i);
             } else if (VK_COMMAND_BUFFER_LEVEL_PRIMARY == pSubCB->createInfo.level) {
-                skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                    __LINE__, DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
-                                    "vkCmdExecuteCommands() called w/ Primary Cmd Buffer 0x%p in element %u of pCommandBuffers "
-                                    "array. All cmd buffers in pCommandBuffers array must be secondary.",
-                                    (void *)pCommandBuffers[i], i);
+                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                     __LINE__, DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
+                                     "vkCmdExecuteCommands() called w/ Primary Cmd Buffer 0x%p in element %u of pCommandBuffers "
+                                     "array. All cmd buffers in pCommandBuffers array must be secondary.",
+                                     (void *)pCommandBuffers[i], i);
             } else if (pCB->activeRenderPass) { // Secondary CB w/i RenderPass must have *CONTINUE_BIT set
+                auto secondary_rp_node = getRenderPass(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass);
                 if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
-                    skipCall |= log_msg(
+                    skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)pCommandBuffers[i], __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
                         "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) executed within render pass (0x%" PRIxLEAST64
@@ -9265,14 +10016,19 @@
                         (void *)pCommandBuffers[i], (uint64_t)pCB->activeRenderPass->renderPass);
                 } else {
                     // Make sure render pass is compatible with parent command buffer pass if has continue
-                    skipCall |= validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->renderPass, pCommandBuffers[i],
-                                                                pSubCB->beginInfo.pInheritanceInfo->renderPass);
-                    skipCall |= validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB);
+                    if (pCB->activeRenderPass->renderPass != secondary_rp_node->renderPass) {
+                        skip_call |= validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->pCreateInfo,
+                                                                    pCommandBuffers[i], secondary_rp_node->pCreateInfo);
+                    }
+                    //  If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB
+                    skip_call |= validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB);
                 }
                 string errorString = "";
-                if (!verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->renderPass,
-                                                     pSubCB->beginInfo.pInheritanceInfo->renderPass, errorString)) {
-                    skipCall |= log_msg(
+                // secondaryCB must have been created w/ RP compatible w/ primaryCB active renderpass
+                if ((pCB->activeRenderPass->renderPass != secondary_rp_node->renderPass) &&
+                    !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->pCreateInfo, secondary_rp_node->pCreateInfo,
+                                                     errorString)) {
+                    skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)pCommandBuffers[i], __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
                         "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) w/ render pass (0x%" PRIxLEAST64
@@ -9280,28 +10036,15 @@
                         (void *)pCommandBuffers[i], (uint64_t)pSubCB->beginInfo.pInheritanceInfo->renderPass, (void *)commandBuffer,
                         (uint64_t)pCB->activeRenderPass->renderPass, errorString.c_str());
                 }
-                //  If framebuffer for secondary CB is not NULL, then it must match FB from vkCmdBeginRenderPass()
-                //   that this CB will be executed in AND framebuffer must have been created w/ RP compatible w/ renderpass
-                if (pSubCB->beginInfo.pInheritanceInfo->framebuffer) {
-                    if (pSubCB->beginInfo.pInheritanceInfo->framebuffer != pCB->activeRenderPassBeginInfo.framebuffer) {
-                        skipCall |= log_msg(
-                            dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            (uint64_t)pCommandBuffers[i], __LINE__, DRAWSTATE_FRAMEBUFFER_INCOMPATIBLE, "DS",
-                            "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) references framebuffer (0x%" PRIxLEAST64
-                            ") that does not match framebuffer (0x%" PRIxLEAST64 ") in active renderpass (0x%" PRIxLEAST64 ").",
-                            (void *)pCommandBuffers[i], (uint64_t)pSubCB->beginInfo.pInheritanceInfo->framebuffer,
-                            (uint64_t)pCB->activeRenderPassBeginInfo.framebuffer, (uint64_t)pCB->activeRenderPass->renderPass);
-                    }
-                }
             }
             // TODO(mlentine): Move more logic into this method
-            skipCall |= validateSecondaryCommandBufferState(dev_data, pCB, pSubCB);
-            skipCall |= validateCommandBufferState(dev_data, pSubCB);
+            skip_call |= validateSecondaryCommandBufferState(dev_data, pCB, pSubCB);
+            skip_call |= validateCommandBufferState(dev_data, pSubCB);
             // Secondary cmdBuffers are considered pending execution starting w/
             // being recorded
             if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) {
                 if (dev_data->globalInFlightCmdBuffers.find(pSubCB->commandBuffer) != dev_data->globalInFlightCmdBuffers.end()) {
-                    skipCall |= log_msg(
+                    skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, "DS",
                         "Attempt to simultaneously execute CB 0x%" PRIxLEAST64 " w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT "
@@ -9310,19 +10053,19 @@
                 }
                 if (pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) {
                     // Warn that non-simultaneous secondary cmd buffer renders primary non-simultaneous
-                    skipCall |= log_msg(
+                    skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)(pCommandBuffers[i]), __LINE__, DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, "DS",
                         "vkCmdExecuteCommands(): Secondary Command Buffer (0x%" PRIxLEAST64
                         ") does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and will cause primary command buffer "
                         "(0x%" PRIxLEAST64 ") to be treated as if it does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT "
-                                          "set, even though it does.",
+                        "set, even though it does.",
                         (uint64_t)(pCommandBuffers[i]), (uint64_t)(pCB->commandBuffer));
                     pCB->beginInfo.flags &= ~VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
                 }
             }
             if (!pCB->activeQueries.empty() && !dev_data->phys_dev_properties.features.inheritedQueries) {
-                skipCall |=
+                skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             reinterpret_cast<uint64_t>(pCommandBuffers[i]), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
                             "vkCmdExecuteCommands(): Secondary Command Buffer "
@@ -9334,28 +10077,50 @@
             pSubCB->primaryCommandBuffer = pCB->commandBuffer;
             pCB->secondaryCommandBuffers.insert(pSubCB->commandBuffer);
             dev_data->globalInFlightCmdBuffers.insert(pSubCB->commandBuffer);
+            for (auto &function : pSubCB->queryUpdates) {
+                pCB->queryUpdates.push_back(function);
+            }
         }
-        skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdExecuteComands");
-        skipCall |= addCmd(dev_data, pCB, CMD_EXECUTECOMMANDS, "vkCmdExecuteComands()");
+        skip_call |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdExecuteComands");
+        skip_call |= addCmd(dev_data, pCB, CMD_EXECUTECOMMANDS, "vkCmdExecuteComands()");
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->CmdExecuteCommands(commandBuffer, commandBuffersCount, pCommandBuffers);
 }
+// Return true if given range intersects with offset and size, else false
+// Prereq : size > 0 and range->end - range->start > 0. Both of these cases should have already resulted
+//  in an error (During MapMemory and AllocateMemory respectively) so not checking them here
+static bool rangesIntersect(MEMORY_RANGE const *range, VkDeviceSize offset, VkDeviceSize size) {
+    auto range2_end = offset + size - 1;
+    if ((range->start >= offset && range->start <= (range2_end)) || (range->end >= offset && range->end <= range2_end)) {
+        return true;
+    }
+    return false;
+}
 
-static bool ValidateMapImageLayouts(VkDevice device, VkDeviceMemory mem) {
+// For any image objects that overlap mapped memory, verify that their layouts are PREINIT or GENERAL
+static bool ValidateMapImageLayouts(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) {
     bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    auto mem_data = dev_data->memObjMap.find(mem);
-    if ((mem_data != dev_data->memObjMap.end()) && (mem_data->second.image != VK_NULL_HANDLE)) {
-        std::vector<VkImageLayout> layouts;
-        if (FindLayouts(dev_data, mem_data->second.image, layouts)) {
-            for (auto layout : layouts) {
-                if (layout != VK_IMAGE_LAYOUT_PREINITIALIZED && layout != VK_IMAGE_LAYOUT_GENERAL) {
-                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
-                                         __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", "Cannot map an image with layout %s. Only "
-                                                                                         "GENERAL or PREINITIALIZED are supported.",
-                                         string_VkImageLayout(layout));
+    auto mem_info = getMemObjInfo(dev_data, mem);
+    if (mem_info) {
+        // Iterate over all bound image ranges and verify that for any that overlap the
+        //  map ranges, the layouts are VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERAL
+        // TODO : This can be optimized if we store ranges based on starting address and early exit when we pass our range
+        for (auto range : mem_info->image_ranges) {
+            if (rangesIntersect(&range, offset, size)) {
+                std::vector<VkImageLayout> layouts;
+                if (FindLayouts(dev_data, VkImage(range.handle), layouts)) {
+                    for (auto layout : layouts) {
+                        if (layout != VK_IMAGE_LAYOUT_PREINITIALIZED && layout != VK_IMAGE_LAYOUT_GENERAL) {
+                            skip_call |=
+                                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                        __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", "Cannot map an image with layout %s. Only "
+                                                                                        "GENERAL or PREINITIALIZED are supported.",
+                                        string_VkImageLayout(layout));
+                        }
+                    }
                 }
             }
         }
@@ -9371,10 +10136,10 @@
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     std::unique_lock<std::mutex> lock(global_lock);
 #if MTMERGESOURCE
-    DEVICE_MEM_INFO *pMemObj = get_mem_obj_info(dev_data, mem);
+    DEVICE_MEM_INFO *pMemObj = getMemObjInfo(dev_data, mem);
     if (pMemObj) {
         pMemObj->valid = true;
-        if ((dev_data->phys_dev_mem_props.memoryTypes[pMemObj->allocInfo.memoryTypeIndex].propertyFlags &
+        if ((dev_data->phys_dev_mem_props.memoryTypes[pMemObj->alloc_info.memoryTypeIndex].propertyFlags &
              VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
             skip_call =
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
@@ -9382,9 +10147,9 @@
                         "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj 0x%" PRIxLEAST64, (uint64_t)mem);
         }
     }
-    skip_call |= validateMemRange(dev_data, mem, offset, size);
+    skip_call |= ValidateMapMemRange(dev_data, mem, offset, size);
 #endif
-    skip_call |= ValidateMapImageLayouts(device, mem);
+    skip_call |= ValidateMapImageLayouts(device, mem, offset, size);
     lock.unlock();
 
     if (!skip_call) {
@@ -9403,90 +10168,91 @@
 
 VKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory mem) {
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
+    bool skip_call = false;
 
     std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= deleteMemRanges(my_data, mem);
+    skip_call |= deleteMemRanges(my_data, mem);
     lock.unlock();
-    if (!skipCall) {
+    if (!skip_call) {
         my_data->device_dispatch_table->UnmapMemory(device, mem);
     }
 }
 
 static bool validateMemoryIsMapped(layer_data *my_data, const char *funcName, uint32_t memRangeCount,
                                    const VkMappedMemoryRange *pMemRanges) {
-    bool skipCall = false;
+    bool skip_call = false;
     for (uint32_t i = 0; i < memRangeCount; ++i) {
-        auto mem_element = my_data->memObjMap.find(pMemRanges[i].memory);
-        if (mem_element != my_data->memObjMap.end()) {
-            if (mem_element->second.memRange.offset > pMemRanges[i].offset) {
-                skipCall |= log_msg(
+        auto mem_info = getMemObjInfo(my_data, pMemRanges[i].memory);
+        if (mem_info) {
+            if (mem_info->mem_range.offset > pMemRanges[i].offset) {
+                skip_call |=
+                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            (uint64_t)pMemRanges[i].memory, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
+                            "%s: Flush/Invalidate offset (" PRINTF_SIZE_T_SPECIFIER ") is less than Memory Object's offset "
+                            "(" PRINTF_SIZE_T_SPECIFIER ").",
+                            funcName, static_cast<size_t>(pMemRanges[i].offset), static_cast<size_t>(mem_info->mem_range.offset));
+            }
+
+            const uint64_t my_dataTerminus = (mem_info->mem_range.size == VK_WHOLE_SIZE)
+                                                 ? mem_info->alloc_info.allocationSize
+                                                 : (mem_info->mem_range.offset + mem_info->mem_range.size);
+            if (pMemRanges[i].size != VK_WHOLE_SIZE && (my_dataTerminus < (pMemRanges[i].offset + pMemRanges[i].size))) {
+                skip_call |= log_msg(
                     my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                     (uint64_t)pMemRanges[i].memory, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
-                    "%s: Flush/Invalidate offset (" PRINTF_SIZE_T_SPECIFIER ") is less than Memory Object's offset "
+                    "%s: Flush/Invalidate upper-bound (" PRINTF_SIZE_T_SPECIFIER ") exceeds the Memory Object's upper-bound "
                     "(" PRINTF_SIZE_T_SPECIFIER ").",
-                    funcName, static_cast<size_t>(pMemRanges[i].offset), static_cast<size_t>(mem_element->second.memRange.offset));
-            }
-            if ((mem_element->second.memRange.size != VK_WHOLE_SIZE) &&
-                ((mem_element->second.memRange.offset + mem_element->second.memRange.size) <
-                 (pMemRanges[i].offset + pMemRanges[i].size))) {
-                skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)pMemRanges[i].memory, __LINE__,
-                                    MEMTRACK_INVALID_MAP, "MEM", "%s: Flush/Invalidate upper-bound (" PRINTF_SIZE_T_SPECIFIER
-                                                                 ") exceeds the Memory Object's upper-bound "
-                                                                 "(" PRINTF_SIZE_T_SPECIFIER ").",
-                                    funcName, static_cast<size_t>(pMemRanges[i].offset + pMemRanges[i].size),
-                                    static_cast<size_t>(mem_element->second.memRange.offset + mem_element->second.memRange.size));
+                    funcName, static_cast<size_t>(pMemRanges[i].offset + pMemRanges[i].size), static_cast<size_t>(my_dataTerminus));
             }
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 static bool validateAndCopyNoncoherentMemoryToDriver(layer_data *my_data, uint32_t memRangeCount,
                                                      const VkMappedMemoryRange *pMemRanges) {
-    bool skipCall = false;
+    bool skip_call = false;
     for (uint32_t i = 0; i < memRangeCount; ++i) {
-        auto mem_element = my_data->memObjMap.find(pMemRanges[i].memory);
-        if (mem_element != my_data->memObjMap.end()) {
-            if (mem_element->second.pData) {
-                VkDeviceSize size = mem_element->second.memRange.size;
+        auto mem_info = getMemObjInfo(my_data, pMemRanges[i].memory);
+        if (mem_info) {
+            if (mem_info->p_data) {
+                VkDeviceSize size = mem_info->mem_range.size;
                 VkDeviceSize half_size = (size / 2);
-                char *data = static_cast<char *>(mem_element->second.pData);
+                char *data = static_cast<char *>(mem_info->p_data);
                 for (auto j = 0; j < half_size; ++j) {
                     if (data[j] != NoncoherentMemoryFillValue) {
-                        skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                            VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)pMemRanges[i].memory, __LINE__,
-                                            MEMTRACK_INVALID_MAP, "MEM", "Memory overflow was detected on mem obj 0x%" PRIxLEAST64,
-                                            (uint64_t)pMemRanges[i].memory);
+                        skip_call |= log_msg(
+                            my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            (uint64_t)pMemRanges[i].memory, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
+                            "Memory overflow was detected on mem obj 0x%" PRIxLEAST64, (uint64_t)pMemRanges[i].memory);
                     }
                 }
                 for (auto j = size + half_size; j < 2 * size; ++j) {
                     if (data[j] != NoncoherentMemoryFillValue) {
-                        skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                            VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)pMemRanges[i].memory, __LINE__,
-                                            MEMTRACK_INVALID_MAP, "MEM", "Memory overflow was detected on mem obj 0x%" PRIxLEAST64,
-                                            (uint64_t)pMemRanges[i].memory);
+                        skip_call |= log_msg(
+                            my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            (uint64_t)pMemRanges[i].memory, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
+                            "Memory overflow was detected on mem obj 0x%" PRIxLEAST64, (uint64_t)pMemRanges[i].memory);
                     }
                 }
-                memcpy(mem_element->second.pDriverData, static_cast<void *>(data + (size_t)(half_size)), (size_t)(size));
+                memcpy(mem_info->p_driver_data, static_cast<void *>(data + (size_t)(half_size)), (size_t)(size));
             }
         }
     }
-    return skipCall;
+    return skip_call;
 }
 
 VkResult VKAPI_CALL
 FlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange *pMemRanges) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validateAndCopyNoncoherentMemoryToDriver(my_data, memRangeCount, pMemRanges);
-    skipCall |= validateMemoryIsMapped(my_data, "vkFlushMappedMemoryRanges", memRangeCount, pMemRanges);
+    skip_call |= validateAndCopyNoncoherentMemoryToDriver(my_data, memRangeCount, pMemRanges);
+    skip_call |= validateMemoryIsMapped(my_data, "vkFlushMappedMemoryRanges", memRangeCount, pMemRanges);
     lock.unlock();
-    if (!skipCall) {
+    if (!skip_call) {
         result = my_data->device_dispatch_table->FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
     }
     return result;
@@ -9495,13 +10261,13 @@
 VkResult VKAPI_CALL
 InvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange *pMemRanges) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validateMemoryIsMapped(my_data, "vkInvalidateMappedMemoryRanges", memRangeCount, pMemRanges);
+    skip_call |= validateMemoryIsMapped(my_data, "vkInvalidateMappedMemoryRanges", memRangeCount, pMemRanges);
     lock.unlock();
-    if (!skipCall) {
+    if (!skip_call) {
         result = my_data->device_dispatch_table->InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges);
     }
     return result;
@@ -9510,36 +10276,35 @@
 VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memoryOffset) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto image_node = dev_data->imageMap.find(image);
-    if (image_node != dev_data->imageMap.end()) {
+    auto image_node = getImageNode(dev_data, image);
+    if (image_node) {
         // Track objects tied to memory
         uint64_t image_handle = reinterpret_cast<uint64_t &>(image);
-        skipCall = set_mem_binding(dev_data, mem, image_handle, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkBindImageMemory");
+        skip_call = set_mem_binding(dev_data, mem, image_handle, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkBindImageMemory");
         VkMemoryRequirements memRequirements;
         lock.unlock();
         dev_data->device_dispatch_table->GetImageMemoryRequirements(device, image, &memRequirements);
         lock.lock();
 
         // Track and validate bound memory range information
-        const auto &memEntry = dev_data->memObjMap.find(mem);
-        if (memEntry != dev_data->memObjMap.end()) {
+        auto mem_info = getMemObjInfo(dev_data, mem);
+        if (mem_info) {
             const MEMORY_RANGE range =
-                insert_memory_ranges(image_handle, mem, memoryOffset, memRequirements, memEntry->second.imageRanges);
-            skipCall |=
-                validate_memory_range(dev_data, memEntry->second.bufferRanges, range, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+                insert_memory_ranges(image_handle, mem, memoryOffset, memRequirements, mem_info->image_ranges);
+            skip_call |= validate_memory_range(dev_data, mem_info->buffer_ranges, range, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+            skip_call |= ValidateMemoryTypes(dev_data, mem_info, memRequirements.memoryTypeBits, "vkBindImageMemory");
         }
 
         print_mem_list(dev_data);
         lock.unlock();
-        if (!skipCall) {
+        if (!skip_call) {
             result = dev_data->device_dispatch_table->BindImageMemory(device, image, mem, memoryOffset);
             lock.lock();
-            dev_data->memObjMap[mem].image = image;
-            image_node->second.mem = mem;
-            image_node->second.memOffset = memoryOffset;
-            image_node->second.memSize = memRequirements.size;
+            image_node->mem = mem;
+            image_node->memOffset = memoryOffset;
+            image_node->memSize = memRequirements.size;
             lock.unlock();
         }
     } else {
@@ -9556,11 +10321,11 @@
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    auto event_node = dev_data->eventMap.find(event);
-    if (event_node != dev_data->eventMap.end()) {
-        event_node->second.needsSignaled = false;
-        event_node->second.stageMask = VK_PIPELINE_STAGE_HOST_BIT;
-        if (event_node->second.write_in_use) {
+    auto event_node = getEventNode(dev_data, event);
+    if (event_node) {
+        event_node->needsSignaled = false;
+        event_node->stageMask = VK_PIPELINE_STAGE_HOST_BIT;
+        if (event_node->write_in_use) {
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,
                                  reinterpret_cast<const uint64_t &>(event), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
                                  "Cannot call vkSetEvent() on event 0x%" PRIxLEAST64 " that is already in use by a command buffer.",
@@ -9588,24 +10353,16 @@
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
+    auto pFence = getFenceNode(dev_data, fence);
+    auto pQueue = getQueueNode(dev_data, queue);
+
     // First verify that fence is not in use
+    skip_call |= ValidateFenceForSubmit(dev_data, pFence);
+
     if (fence != VK_NULL_HANDLE) {
-        auto fence_data = dev_data->fenceMap.find(fence);
-        if ((bindInfoCount != 0) && fence_data->second.in_use.load()) {
-            skip_call |=
-                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
-                        reinterpret_cast<uint64_t &>(fence), __LINE__, DRAWSTATE_INVALID_FENCE, "DS",
-                        "Fence 0x%" PRIx64 " is already in use by another submission.", reinterpret_cast<uint64_t &>(fence));
-        }
-        if (!fence_data->second.needsSignaled) {
-            skip_call |=
-                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,
-                        reinterpret_cast<uint64_t &>(fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
-                        "Fence 0x%" PRIxLEAST64 " submitted in SIGNALED state.  Fences must be reset before being submitted",
-                        reinterpret_cast<uint64_t &>(fence));
-        }
-        trackCommandBuffers(dev_data, queue, 0, nullptr, fence);
+        SubmitFence(pQueue, pFence);
     }
+
     for (uint32_t bindIdx = 0; bindIdx < bindInfoCount; ++bindIdx) {
         const VkBindSparseInfo &bindInfo = pBindInfo[bindIdx];
         // Track objects tied to memory
@@ -9634,10 +10391,11 @@
             }
         }
         for (uint32_t i = 0; i < bindInfo.waitSemaphoreCount; ++i) {
-            const VkSemaphore &semaphore = bindInfo.pWaitSemaphores[i];
-            if (dev_data->semaphoreMap.find(semaphore) != dev_data->semaphoreMap.end()) {
-                if (dev_data->semaphoreMap[semaphore].signaled) {
-                    dev_data->semaphoreMap[semaphore].signaled = false;
+            VkSemaphore semaphore = bindInfo.pWaitSemaphores[i];
+            auto pSemaphore = getSemaphoreNode(dev_data, semaphore);
+            if (pSemaphore) {
+                if (pSemaphore->signaled) {
+                    pSemaphore->signaled = false;
                 } else {
                     skip_call |=
                         log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
@@ -9649,9 +10407,10 @@
             }
         }
         for (uint32_t i = 0; i < bindInfo.signalSemaphoreCount; ++i) {
-            const VkSemaphore &semaphore = bindInfo.pSignalSemaphores[i];
-            if (dev_data->semaphoreMap.find(semaphore) != dev_data->semaphoreMap.end()) {
-                if (dev_data->semaphoreMap[semaphore].signaled) {
+            VkSemaphore semaphore = bindInfo.pSignalSemaphores[i];
+            auto pSemaphore = getSemaphoreNode(dev_data, semaphore);
+            if (pSemaphore) {
+                if (pSemaphore->signaled) {
                     skip_call =
                         log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
                                 reinterpret_cast<const uint64_t &>(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
@@ -9659,7 +10418,7 @@
                                 ", but that semaphore is already signaled.",
                                 reinterpret_cast<const uint64_t &>(queue), reinterpret_cast<const uint64_t &>(semaphore));
                 }
-                dev_data->semaphoreMap[semaphore].signaled = true;
+                pSemaphore->signaled = true;
             }
         }
     }
@@ -9694,6 +10453,7 @@
         std::lock_guard<std::mutex> lock(global_lock);
         dev_data->eventMap[*pEvent].needsSignaled = false;
         dev_data->eventMap[*pEvent].in_use.store(0);
+        dev_data->eventMap[*pEvent].write_in_use = 0;
         dev_data->eventMap[*pEvent].stageMask = VkPipelineStageFlags(0);
     }
     return result;
@@ -9706,9 +10466,8 @@
     VkResult result = dev_data->device_dispatch_table->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
 
     if (VK_SUCCESS == result) {
-        SWAPCHAIN_NODE *psc_node = new SWAPCHAIN_NODE(pCreateInfo);
         std::lock_guard<std::mutex> lock(global_lock);
-        dev_data->device_extensions.swapchainMap[*pSwapchain] = psc_node;
+        dev_data->device_extensions.swapchainMap[*pSwapchain] = unique_ptr<SWAPCHAIN_NODE>(new SWAPCHAIN_NODE(pCreateInfo));
     }
 
     return result;
@@ -9717,13 +10476,13 @@
 VKAPI_ATTR void VKAPI_CALL
 DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
+    bool skip_call = false;
 
     std::unique_lock<std::mutex> lock(global_lock);
-    auto swapchain_data = dev_data->device_extensions.swapchainMap.find(swapchain);
-    if (swapchain_data != dev_data->device_extensions.swapchainMap.end()) {
-        if (swapchain_data->second->images.size() > 0) {
-            for (auto swapchain_image : swapchain_data->second->images) {
+    auto swapchain_data = getSwapchainNode(dev_data, swapchain);
+    if (swapchain_data) {
+        if (swapchain_data->images.size() > 0) {
+            for (auto swapchain_image : swapchain_data->images) {
                 auto image_sub = dev_data->imageSubresourceMap.find(swapchain_image);
                 if (image_sub != dev_data->imageSubresourceMap.end()) {
                     for (auto imgsubpair : image_sub->second) {
@@ -9734,16 +10493,15 @@
                     }
                     dev_data->imageSubresourceMap.erase(image_sub);
                 }
-                skipCall = clear_object_binding(dev_data, (uint64_t)swapchain_image,
-                                                VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+                skip_call =
+                    clear_object_binding(dev_data, (uint64_t)swapchain_image, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
                 dev_data->imageMap.erase(swapchain_image);
             }
         }
-        delete swapchain_data->second;
         dev_data->device_extensions.swapchainMap.erase(swapchain);
     }
     lock.unlock();
-    if (!skipCall)
+    if (!skip_call)
         dev_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain, pAllocator);
 }
 
@@ -9758,8 +10516,8 @@
             return result;
         std::lock_guard<std::mutex> lock(global_lock);
         const size_t count = *pCount;
-        auto swapchain_node = dev_data->device_extensions.swapchainMap[swapchain];
-        if (!swapchain_node->images.empty()) {
+        auto swapchain_node = getSwapchainNode(dev_data, swapchain);
+        if (swapchain_node && !swapchain_node->images.empty()) {
             // TODO : Not sure I like the memcmp here, but it works
             const bool mismatch = (swapchain_node->images.size() != count ||
                                    memcmp(&swapchain_node->images[0], pSwapchainImages, sizeof(swapchain_node->images[0]) * count));
@@ -9776,16 +10534,20 @@
             IMAGE_LAYOUT_NODE image_layout_node;
             image_layout_node.layout = VK_IMAGE_LAYOUT_UNDEFINED;
             image_layout_node.format = swapchain_node->createInfo.imageFormat;
+            // Add imageMap entries for each swapchain image
+            VkImageCreateInfo image_ci = {};
+            image_ci.mipLevels = 1;
+            image_ci.arrayLayers = swapchain_node->createInfo.imageArrayLayers;
+            image_ci.usage = swapchain_node->createInfo.imageUsage;
+            image_ci.format = swapchain_node->createInfo.imageFormat;
+            image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
+            image_ci.extent.width = swapchain_node->createInfo.imageExtent.width;
+            image_ci.extent.height = swapchain_node->createInfo.imageExtent.height;
+            image_ci.sharingMode = swapchain_node->createInfo.imageSharingMode;
+            dev_data->imageMap[pSwapchainImages[i]] = unique_ptr<IMAGE_NODE>(new IMAGE_NODE(pSwapchainImages[i], &image_ci));
             auto &image_node = dev_data->imageMap[pSwapchainImages[i]];
-            image_node.createInfo.mipLevels = 1;
-            image_node.createInfo.arrayLayers = swapchain_node->createInfo.imageArrayLayers;
-            image_node.createInfo.usage = swapchain_node->createInfo.imageUsage;
-            image_node.createInfo.format = swapchain_node->createInfo.imageFormat;
-            image_node.createInfo.extent.width = swapchain_node->createInfo.imageExtent.width;
-            image_node.createInfo.extent.height = swapchain_node->createInfo.imageExtent.height;
-            image_node.createInfo.sharingMode = swapchain_node->createInfo.imageSharingMode;
-            image_node.valid = false;
-            image_node.mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY;
+            image_node->valid = false;
+            image_node->mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY;
             swapchain_node->images.push_back(pSwapchainImages[i]);
             ImageSubresourcePair subpair = {pSwapchainImages[i], false, VkImageSubresource()};
             dev_data->imageSubresourceMap[pSwapchainImages[i]].push_back(subpair);
@@ -9798,55 +10560,57 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
 
-    if (pPresentInfo) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) {
-            const VkSemaphore &semaphore = pPresentInfo->pWaitSemaphores[i];
-            if (dev_data->semaphoreMap.find(semaphore) != dev_data->semaphoreMap.end()) {
-                if (dev_data->semaphoreMap[semaphore].signaled) {
-                    dev_data->semaphoreMap[semaphore].signaled = false;
-                } else {
-                    skip_call |=
-                        log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
-                                "Queue 0x%" PRIx64 " is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.",
-                                reinterpret_cast<uint64_t &>(queue), reinterpret_cast<const uint64_t &>(semaphore));
-                }
-            }
+    std::lock_guard<std::mutex> lock(global_lock);
+    for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) {
+        auto pSemaphore = getSemaphoreNode(dev_data, pPresentInfo->pWaitSemaphores[i]);
+        if (pSemaphore && !pSemaphore->signaled) {
+            skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                            VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
+                            "Queue 0x%" PRIx64 " is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.",
+                            reinterpret_cast<uint64_t &>(queue), reinterpret_cast<const uint64_t &>(pPresentInfo->pWaitSemaphores[i]));
         }
-        VkDeviceMemory mem;
-        for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
-            auto swapchain_data = dev_data->device_extensions.swapchainMap.find(pPresentInfo->pSwapchains[i]);
-            if (swapchain_data != dev_data->device_extensions.swapchainMap.end() &&
-                pPresentInfo->pImageIndices[i] < swapchain_data->second->images.size()) {
-                VkImage image = swapchain_data->second->images[pPresentInfo->pImageIndices[i]];
-#if MTMERGESOURCE
-                skip_call |=
-                    get_mem_binding_from_object(dev_data, (uint64_t)(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
-                skip_call |= validate_memory_is_valid(dev_data, mem, "vkQueuePresentKHR()", image);
-#endif
-                vector<VkImageLayout> layouts;
-                if (FindLayouts(dev_data, image, layouts)) {
-                    for (auto layout : layouts) {
-                        if (layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
-                            skip_call |=
+    }
+
+    for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
+        auto swapchain_data = getSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]);
+        if (swapchain_data && pPresentInfo->pImageIndices[i] < swapchain_data->images.size()) {
+            VkImage image = swapchain_data->images[pPresentInfo->pImageIndices[i]];
+            skip_call |= validate_memory_is_valid(dev_data, getImageNode(dev_data, image)->mem, "vkQueuePresentKHR()", image);
+            vector<VkImageLayout> layouts;
+            if (FindLayouts(dev_data, image, layouts)) {
+                for (auto layout : layouts) {
+                    if (layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
+                        skip_call |=
                                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
                                         reinterpret_cast<uint64_t &>(queue), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
                                         "Images passed to present must be in layout "
                                         "PRESENT_SOURCE_KHR but is in %s",
                                         string_VkImageLayout(layout));
-                        }
                     }
                 }
             }
         }
     }
 
-    if (!skip_call)
-        result = dev_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo);
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+
+    VkResult result = dev_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo);
+
+    if (result != VK_ERROR_VALIDATION_FAILED_EXT) {
+        // Semaphore waits occur before error generation, if the call reached
+        // the ICD. (Confirm?)
+        for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) {
+            auto pSemaphore = getSemaphoreNode(dev_data, pPresentInfo->pWaitSemaphores[i]);
+            if (pSemaphore && pSemaphore->signaled) {
+                pSemaphore->signaled = false;
+            }
+        }
+    }
 
     return result;
 }
@@ -9854,33 +10618,152 @@
 VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
                                                    VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
 
     std::unique_lock<std::mutex> lock(global_lock);
-    if (semaphore != VK_NULL_HANDLE &&
-        dev_data->semaphoreMap.find(semaphore) != dev_data->semaphoreMap.end()) {
-        if (dev_data->semaphoreMap[semaphore].signaled) {
-            skipCall = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
-                               reinterpret_cast<const uint64_t &>(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
-                               "vkAcquireNextImageKHR: Semaphore must not be currently signaled or in a wait state");
-        }
-        dev_data->semaphoreMap[semaphore].signaled = true;
+    auto pSemaphore = getSemaphoreNode(dev_data, semaphore);
+    if (pSemaphore && pSemaphore->signaled) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
+                             reinterpret_cast<const uint64_t &>(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
+                             "vkAcquireNextImageKHR: Semaphore must not be currently signaled or in a wait state");
     }
-    auto fence_data = dev_data->fenceMap.find(fence);
-    if (fence_data != dev_data->fenceMap.end()) {
-        fence_data->second.swapchain = swapchain;
+
+    auto pFence = getFenceNode(dev_data, fence);
+    if (pFence) {
+        skip_call |= ValidateFenceForSubmit(dev_data, pFence);
     }
     lock.unlock();
 
-    if (!skipCall) {
-        result =
+    if (skip_call)
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+
+    VkResult result =
             dev_data->device_dispatch_table->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+
+    lock.lock();
+    if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) {
+        if (pFence) {
+            pFence->state = FENCE_INFLIGHT;
+        }
+
+        // A successful call to AcquireNextImageKHR counts as a signal operation on semaphore
+        if (pSemaphore) {
+            pSemaphore->signaled = true;
+        }
     }
+    lock.unlock();
 
     return result;
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
+                                                        VkPhysicalDevice *pPhysicalDevices) {
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    if (my_data->instance_state) {
+        // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS
+        if (NULL == pPhysicalDevices) {
+            my_data->instance_state->vkEnumeratePhysicalDevicesState = QUERY_COUNT;
+        } else {
+            if (UNCALLED == my_data->instance_state->vkEnumeratePhysicalDevicesState) {
+                // Flag warning here. You can call this without having queried the count, but it may not be
+                // robust on platforms with multiple physical devices.
+                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
+                                    0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL",
+                                    "Call sequence has vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first "
+                                    "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount.");
+            } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state
+            else if (my_data->instance_state->physical_devices_count != *pPhysicalDeviceCount) {
+                // Having actual count match count from app is not a requirement, so this can be a warning
+                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                                    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
+                                    "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count "
+                                    "supported by this instance is %u.",
+                                    *pPhysicalDeviceCount, my_data->instance_state->physical_devices_count);
+            }
+            my_data->instance_state->vkEnumeratePhysicalDevicesState = QUERY_DETAILS;
+        }
+        if (skip_call) {
+            return VK_ERROR_VALIDATION_FAILED_EXT;
+        }
+        VkResult result =
+            my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
+        if (NULL == pPhysicalDevices) {
+            my_data->instance_state->physical_devices_count = *pPhysicalDeviceCount;
+        } else { // Save physical devices
+            for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
+                layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map);
+                phy_dev_data->physical_device_state = unique_ptr<PHYSICAL_DEVICE_STATE>(new PHYSICAL_DEVICE_STATE());
+                // Init actual features for each physical device
+                my_data->instance_dispatch_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i],
+                                                                            &phy_dev_data->physical_device_features);
+            }
+        }
+        return result;
+    } else {
+        log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
+                DEVLIMITS_INVALID_INSTANCE, "DL", "Invalid instance (0x%" PRIxLEAST64 ") passed into vkEnumeratePhysicalDevices().",
+                (uint64_t)instance);
+    }
+    return VK_ERROR_VALIDATION_FAILED_EXT;
+}
+
+VKAPI_ATTR void VKAPI_CALL
+GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
+    VkQueueFamilyProperties *pQueueFamilyProperties) {
+    bool skip_call = false;
+    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    if (phy_dev_data->physical_device_state) {
+        if (NULL == pQueueFamilyProperties) {
+            phy_dev_data->physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
+        }
+        else {
+            // Verify that for each physical device, this function is called first with NULL pQueueFamilyProperties ptr in order to
+            // get count
+            if (UNCALLED == phy_dev_data->physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
+                skip_call |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL",
+                    "Call sequence has vkGetPhysicalDeviceQueueFamilyProperties() w/ non-NULL "
+                    "pQueueFamilyProperties. You should first call vkGetPhysicalDeviceQueueFamilyProperties() w/ "
+                    "NULL pQueueFamilyProperties to query pCount.");
+            }
+            // Then verify that pCount that is passed in on second call matches what was returned
+            if (phy_dev_data->physical_device_state->queueFamilyPropertiesCount != *pCount) {
+
+                // TODO: this is not a requirement of the Valid Usage section for vkGetPhysicalDeviceQueueFamilyProperties, so
+                // provide as warning
+                skip_call |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
+                    "Call to vkGetPhysicalDeviceQueueFamilyProperties() w/ pCount value %u, but actual count "
+                    "supported by this physicalDevice is %u.",
+                    *pCount, phy_dev_data->physical_device_state->queueFamilyPropertiesCount);
+            }
+            phy_dev_data->physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
+        }
+        if (skip_call) {
+            return;
+        }
+        phy_dev_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount,
+            pQueueFamilyProperties);
+        if (NULL == pQueueFamilyProperties) {
+            phy_dev_data->physical_device_state->queueFamilyPropertiesCount = *pCount;
+        }
+        else { // Save queue family properties
+            phy_dev_data->queue_family_properties.reserve(*pCount);
+            for (uint32_t i = 0; i < *pCount; i++) {
+                phy_dev_data->queue_family_properties.emplace_back(new VkQueueFamilyProperties(pQueueFamilyProperties[i]));
+            }
+        }
+        return;
+    }
+    else {
+        log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
+            __LINE__, DEVLIMITS_INVALID_PHYSICAL_DEVICE, "DL",
+            "Invalid physicalDevice (0x%" PRIxLEAST64 ") passed into vkGetPhysicalDeviceQueueFamilyProperties().",
+            (uint64_t)physicalDevice);
+    }
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL
 CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
                              const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
@@ -9889,7 +10772,7 @@
     VkResult res = pTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
     if (VK_SUCCESS == res) {
         std::lock_guard<std::mutex> lock(global_lock);
-        res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
+        res = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
     }
     return res;
 }
@@ -9912,6 +10795,24 @@
                                                             pMsg);
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, global_layer.layerName))
+        return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
+
+    return VK_ERROR_LAYER_NOT_PRESENT;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                   const char *pLayerName, uint32_t *pCount,
                                                                   VkExtensionProperties *pProperties) {
@@ -9989,15 +10890,15 @@
         { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) },
         { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) },
         { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) },
+        { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) },
+        { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) },
         { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) },
+        { "vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties) },
+        { "vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties) },
+        { "vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties) },
         { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) },
     };
 
-    // we should never be queried for these commands
-    assert(strcmp(name, "vkEnumerateInstanceLayerProperties") &&
-           strcmp(name, "vkEnumerateInstanceExtensionProperties") &&
-           strcmp(name, "vkEnumerateDeviceLayerProperties"));
-
     for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
         if (!strcmp(core_instance_commands[i].name, name))
             return core_instance_commands[i].proc;
@@ -10188,27 +11089,30 @@
     core_validation::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
 }
 
-// loader-layer interface v0
+// loader-layer interface v0, just wrappers since there is only a layer
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
-    return util_GetExtensionProperties(1, core_validation::instance_extensions, pCount, pProperties);
+    return core_validation::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &core_validation::global_layer, pCount, pProperties);
+    return core_validation::EnumerateInstanceLayerProperties(pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &core_validation::global_layer, pCount, pProperties);
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return core_validation::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                                     const char *pLayerName, uint32_t *pCount,
                                                                                     VkExtensionProperties *pProperties) {
-    // the layer command handles VK_NULL_HANDLE just fine
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
     return core_validation::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
 }
 
@@ -10217,14 +11121,5 @@
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
-    if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties);
-    if (!strcmp(funcName, "vkGetInstanceProcAddr"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr);
-
     return core_validation::GetInstanceProcAddr(instance, funcName);
 }
diff --git a/layers/core_validation.h b/layers/core_validation.h
index d685734..5dcafbb 100644
--- a/layers/core_validation.h
+++ b/layers/core_validation.h
@@ -125,14 +125,7 @@
     VkFormat format;
 };
 
-// Store layouts and pushconstants for PipelineLayout
-struct PIPELINE_LAYOUT_NODE {
-    std::vector<VkDescriptorSetLayout> descriptorSetLayouts;
-    std::vector<cvdescriptorset::DescriptorSetLayout const *> setLayouts;
-    std::vector<VkPushConstantRange> pushConstantRanges;
-};
-
-class PIPELINE_NODE {
+class PIPELINE_NODE : public BASE_NODE {
   public:
     VkPipeline pipeline;
     safe_VkGraphicsPipelineCreateInfo graphicsPipelineCI;
@@ -141,19 +134,21 @@
     uint32_t active_shaders;
     uint32_t duplicate_shaders;
     // Capture which slots (set#->bindings) are actually used by the shaders of this pipeline
-    std::unordered_map<uint32_t, std::unordered_set<uint32_t>> active_slots;
+    std::unordered_map<uint32_t, std::unordered_map<uint32_t, descriptor_req>> active_slots;
     // Vtx input info (if any)
     std::vector<VkVertexInputBindingDescription> vertexBindingDescriptions;
     std::vector<VkVertexInputAttributeDescription> vertexAttributeDescriptions;
     std::vector<VkPipelineColorBlendAttachmentState> attachments;
     bool blendConstantsEnabled; // Blend constants enabled for any attachments
-    RENDER_PASS_NODE *renderPass;
-    PIPELINE_LAYOUT_NODE const *pipelineLayout;
+    // Store RPCI b/c renderPass may be destroyed after Pipeline creation
+    safe_VkRenderPassCreateInfo render_pass_ci;
+    PIPELINE_LAYOUT_NODE pipeline_layout;
 
     // Default constructor
     PIPELINE_NODE()
-        : pipeline{}, graphicsPipelineCI{}, computePipelineCI{}, active_shaders(0), duplicate_shaders(0), active_slots(), vertexBindingDescriptions(),
-          vertexAttributeDescriptions(), attachments(), blendConstantsEnabled(false), renderPass(nullptr), pipelineLayout(nullptr) {}
+        : pipeline{}, graphicsPipelineCI{}, computePipelineCI{}, active_shaders(0), duplicate_shaders(0), active_slots(),
+          vertexBindingDescriptions(), vertexAttributeDescriptions(), attachments(), blendConstantsEnabled(false), render_pass_ci(),
+          pipeline_layout() {}
 
     void initGraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo) {
         graphicsPipelineCI.initialize(pCreateInfo);
@@ -208,20 +203,19 @@
     std::vector<VkQueueFamilyProperties> queue_family_properties;
 };
 
-class FENCE_NODE : public BASE_NODE {
-  public:
-    using BASE_NODE::in_use;
+enum FENCE_STATE { FENCE_UNSIGNALED, FENCE_INFLIGHT, FENCE_RETIRED };
 
-    VkSwapchainKHR swapchain; // Swapchain that this fence is submitted against or NULL
-    bool firstTimeFlag;       // Fence was created in signaled state, avoid warnings for first use
+class FENCE_NODE {
+  public:
+    VkFence fence;
     VkFenceCreateInfo createInfo;
     std::unordered_set<VkQueue> queues;
-    std::vector<VkCommandBuffer> cmdBuffers;
-    bool needsSignaled;
+    std::vector<CB_SUBMISSION> submissions;
     std::vector<VkFence> priorFences;
+    FENCE_STATE state;
 
     // Default constructor
-    FENCE_NODE() : swapchain(VK_NULL_HANDLE), firstTimeFlag(false), needsSignaled(false){};
+    FENCE_NODE() : state(FENCE_UNSIGNALED) {}
 };
 
 class SEMAPHORE_NODE : public BASE_NODE {
@@ -241,14 +235,10 @@
 
 class QUEUE_NODE {
   public:
-    VkDevice device;
+    VkQueue queue;
+    uint32_t queueFamilyIndex;
     std::vector<VkFence> lastFences;
-#if MTMERGE
-    // MTMTODO : merge cmd_buffer data structs here
-    std::list<VkCommandBuffer> pQueueCommandBuffers;
-    std::list<VkDeviceMemory> pMemRefList;
-#endif
-    std::vector<VkCommandBuffer> untrackedCmdBuffers;
+    std::vector<CB_SUBMISSION> untrackedSubmissions;
     std::unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap;
     std::unordered_map<QueryObject, bool> queryToStateMap; // 0 is unavailable, 1 is available
 };
@@ -258,47 +248,17 @@
     VkQueryPoolCreateInfo createInfo;
 };
 
-class FRAMEBUFFER_NODE {
+class FRAMEBUFFER_NODE : BASE_NODE {
   public:
-    VkFramebufferCreateInfo createInfo;
+    using BASE_NODE::in_use;
+    using BASE_NODE::cb_bindings;
+    VkFramebuffer framebuffer;
+    safe_VkFramebufferCreateInfo createInfo;
+    safe_VkRenderPassCreateInfo renderPassCreateInfo;
     std::unordered_set<VkCommandBuffer> referencingCmdBuffers;
     std::vector<MT_FB_ATTACHMENT_INFO> attachments;
-};
-
-struct DESCRIPTOR_POOL_NODE {
-    VkDescriptorPool pool;
-    uint32_t maxSets;                              // Max descriptor sets allowed in this pool
-    uint32_t availableSets;                        // Available descriptor sets in this pool
-
-    VkDescriptorPoolCreateInfo createInfo;
-    std::unordered_set<cvdescriptorset::DescriptorSet *> sets; // Collection of all sets in this pool
-    std::vector<uint32_t> maxDescriptorTypeCount;       // Max # of descriptors of each type in this pool
-    std::vector<uint32_t> availableDescriptorTypeCount; // Available # of descriptors of each type in this pool
-
-    DESCRIPTOR_POOL_NODE(const VkDescriptorPool pool, const VkDescriptorPoolCreateInfo *pCreateInfo)
-        : pool(pool), maxSets(pCreateInfo->maxSets), availableSets(pCreateInfo->maxSets), createInfo(*pCreateInfo),
-          maxDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0), availableDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0) {
-        if (createInfo.poolSizeCount) { // Shadow type struct from ptr into local struct
-            size_t poolSizeCountSize = createInfo.poolSizeCount * sizeof(VkDescriptorPoolSize);
-            createInfo.pPoolSizes = new VkDescriptorPoolSize[poolSizeCountSize];
-            memcpy((void *)createInfo.pPoolSizes, pCreateInfo->pPoolSizes, poolSizeCountSize);
-            // Now set max counts for each descriptor type based on count of that type times maxSets
-            uint32_t i = 0;
-            for (i = 0; i < createInfo.poolSizeCount; ++i) {
-                uint32_t typeIndex = static_cast<uint32_t>(createInfo.pPoolSizes[i].type);
-                // Same descriptor types can appear several times
-                maxDescriptorTypeCount[typeIndex] += createInfo.pPoolSizes[i].descriptorCount;
-                availableDescriptorTypeCount[typeIndex] = maxDescriptorTypeCount[typeIndex];
-            }
-        } else {
-            createInfo.pPoolSizes = NULL; // Make sure this is NULL so we don't try to clean it up
-        }
-    }
-    ~DESCRIPTOR_POOL_NODE() {
-        delete[] createInfo.pPoolSizes;
-        // TODO : pSets are currently freed in deletePools function which uses freeShadowUpdateTree function
-        //  need to migrate that struct to smart ptrs for auto-cleanup
-    }
+    FRAMEBUFFER_NODE(VkFramebuffer fb, const VkFramebufferCreateInfo *pCreateInfo, const VkRenderPassCreateInfo *pRPCI)
+        : framebuffer(fb), createInfo(pCreateInfo), renderPassCreateInfo(pRPCI){};
 };
 
 typedef struct stencil_data {
@@ -306,3 +266,39 @@
     uint32_t writeMask;
     uint32_t reference;
 } CBStencilData;
+
+// Track command pools and their command buffers
+struct COMMAND_POOL_NODE {
+    VkCommandPoolCreateFlags createFlags;
+    uint32_t queueFamilyIndex;
+    // TODO: why is this std::list?
+    std::list<VkCommandBuffer> commandBuffers; // container of cmd buffers allocated from this pool
+};
+
+// Stuff from Device Limits Layer
+enum CALL_STATE {
+    UNCALLED,      // Function has not been called
+    QUERY_COUNT,   // Function called once to query a count
+    QUERY_DETAILS, // Function called w/ a count to query details
+};
+
+struct INSTANCE_STATE {
+    // Track the call state and array size for physical devices
+    CALL_STATE vkEnumeratePhysicalDevicesState;
+    uint32_t physical_devices_count;
+    INSTANCE_STATE() : vkEnumeratePhysicalDevicesState(UNCALLED), physical_devices_count(0) {};
+};
+
+struct PHYSICAL_DEVICE_STATE {
+    // Track the call state and array sizes for various query functions
+    CALL_STATE vkGetPhysicalDeviceQueueFamilyPropertiesState;
+    uint32_t queueFamilyPropertiesCount;
+    CALL_STATE vkGetPhysicalDeviceLayerPropertiesState;
+    CALL_STATE vkGetPhysicalDeviceExtensionPropertiesState;
+    CALL_STATE vkGetPhysicalDeviceFeaturesState;
+    PHYSICAL_DEVICE_STATE()
+        : vkGetPhysicalDeviceQueueFamilyPropertiesState(UNCALLED),
+        vkGetPhysicalDeviceLayerPropertiesState(UNCALLED),
+        vkGetPhysicalDeviceExtensionPropertiesState(UNCALLED),
+        vkGetPhysicalDeviceFeaturesState(UNCALLED) {};
+};
diff --git a/layers/core_validation_error_enums.h b/layers/core_validation_error_enums.h
index e6d0ed3..56a8b2c 100644
--- a/layers/core_validation_error_enums.h
+++ b/layers/core_validation_error_enums.h
@@ -39,6 +39,8 @@
     MEMTRACK_REBIND_OBJECT,                // Non-sparse object bindings are immutable
     MEMTRACK_INVALID_USAGE_FLAG,           // Usage flags specified at image/buffer create conflict w/ use of object
     MEMTRACK_INVALID_MAP,                  // Size flag specified at alloc is too small for mapping range
+    MEMTRACK_INVALID_MEM_TYPE,             // Memory Type mismatch
+    MEMTRACK_OBJECT_NOT_BOUND,             // Image or Buffer used without having memory bound to it
 };
 
 // Draw State ERROR codes
@@ -48,13 +50,11 @@
     DRAWSTATE_NONE,                          // Used for INFO & other non-error messages
     DRAWSTATE_INTERNAL_ERROR,                // Error with DrawState internal data structures
     DRAWSTATE_NO_PIPELINE_BOUND,             // Unable to identify a bound pipeline
-    DRAWSTATE_INVALID_POOL,                  // Invalid DS pool
     DRAWSTATE_INVALID_SET,                   // Invalid DS
     DRAWSTATE_INVALID_RENDER_AREA,           // Invalid renderArea
     DRAWSTATE_INVALID_LAYOUT,                // Invalid DS layout
     DRAWSTATE_INVALID_IMAGE_LAYOUT,          // Invalid Image layout
     DRAWSTATE_INVALID_PIPELINE,              // Invalid Pipeline handle referenced
-    DRAWSTATE_INVALID_PIPELINE_LAYOUT,       // Invalid PipelineLayout
     DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, // Attempt to create a pipeline
                                              // with invalid state
     DRAWSTATE_INVALID_COMMAND_BUFFER,        // Invalid CommandBuffer referenced
@@ -62,7 +62,6 @@
     DRAWSTATE_INVALID_BUFFER,                // Invalid Buffer
     DRAWSTATE_INVALID_QUERY,                 // Invalid Query
     DRAWSTATE_INVALID_FENCE,                 // Invalid Fence
-    DRAWSTATE_INVALID_SEMAPHORE,             // Invalid Semaphore
     DRAWSTATE_INVALID_EVENT,                 // Invalid Event
     DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS,       // binding in vkCmdBindVertexData() too
                                              // large for PSO's
@@ -88,8 +87,10 @@
     DRAWSTATE_CANT_FREE_FROM_NON_FREE_POOL,           // Invalid to call
                                                       // vkFreeDescriptorSets on Sets
                                                       // allocated from a NON_FREE Pool
-    DRAWSTATE_INVALID_UPDATE_INDEX,                   // Index of requested update is invalid for
-                                                      // specified descriptors set
+    DRAWSTATE_INVALID_WRITE_UPDATE,                   // Attempting a write update to a descriptor
+                                                      // set with invalid update state
+    DRAWSTATE_INVALID_COPY_UPDATE,                    // Attempting copy update to a descriptor set
+                                                      // with invalid state
     DRAWSTATE_INVALID_UPDATE_STRUCT,                  // Struct in DS Update tree is of invalid
                                                       // type
     DRAWSTATE_NUM_SAMPLES_MISMATCH,                   // Number of samples in bound PSO does not
@@ -130,12 +131,17 @@
     DRAWSTATE_FRAMEBUFFER_INCOMPATIBLE,         // Incompatible framebuffer between
                                                 // secondary cmdBuffer and active
                                                 // renderPass
+    DRAWSTATE_INVALID_FRAMEBUFFER_CREATE_INFO,  // Invalid VkFramebufferCreateInfo state
     DRAWSTATE_INVALID_RENDERPASS,               // Use of a NULL or otherwise invalid
                                                 // RenderPass object
     DRAWSTATE_INVALID_RENDERPASS_CMD,           // Invalid cmd submitted while a
                                                 // RenderPass is active
     DRAWSTATE_NO_ACTIVE_RENDERPASS,             // Rendering cmd submitted without an active
                                                 // RenderPass
+    DRAWSTATE_INVALID_IMAGE_USAGE,              // Image attachment location conflicts with
+                                                // image's USAGE flags
+    DRAWSTATE_INVALID_ATTACHMENT_INDEX,         // Attachment reference contains an index
+                                                // that is out-of-bounds
     DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED,       // DescriptorSet bound but it was
                                                 // never updated. This is a warning
                                                 // code.
@@ -213,9 +219,12 @@
                                              // must be a valid VkLogicOp value
     DRAWSTATE_INVALID_QUEUE_INDEX,           // Specified queue index exceeds number
                                              // of queried queue families
+    DRAWSTATE_INVALID_QUEUE_FAMILY,          // Command buffer submitted on queue is from
+                                             // a different queue family
     DRAWSTATE_PUSH_CONSTANTS_ERROR,          // Push constants exceed maxPushConstantSize
 };
 
+// Shader Checker ERROR codes
 enum SHADER_CHECKER_ERROR {
     SHADER_CHECKER_NONE,
     SHADER_CHECKER_INTERFACE_TYPE_MISMATCH,    // Type mismatch between shader stages or shader and pipeline
@@ -236,4 +245,15 @@
     SHADER_CHECKER_BAD_CAPABILITY,                          // Shader uses capability not supported by Vulkan (OpenCL features)
 };
 
+// Device Limits ERROR codes
+enum DEV_LIMITS_ERROR {
+    DEVLIMITS_NONE,                          // Used for INFO & other non-error messages
+    DEVLIMITS_INVALID_INSTANCE,              // Invalid instance used
+    DEVLIMITS_INVALID_PHYSICAL_DEVICE,       // Invalid physical device used
+    DEVLIMITS_MISSING_QUERY_COUNT,           // Did not make initial call to an API to query the count
+    DEVLIMITS_MUST_QUERY_COUNT,              // Failed to make initial call to an API to query the count
+    DEVLIMITS_INVALID_FEATURE_REQUESTED,     // App requested a feature not supported by physical device
+    DEVLIMITS_COUNT_MISMATCH,                // App requesting a count value different than actual value
+    DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,  // Invalid queue requested based on queue family properties
+};
 #endif // CORE_VALIDATION_ERROR_ENUMS_H_
diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h
index c039418..f68a451 100644
--- a/layers/core_validation_types.h
+++ b/layers/core_validation_types.h
@@ -54,22 +54,108 @@
 
 // Fwd declarations
 namespace cvdescriptorset {
+class DescriptorSetLayout;
 class DescriptorSet;
 };
 
+struct GLOBAL_CB_NODE;
+
 class BASE_NODE {
   public:
+    // Track when object is being used by an in-flight command buffer
     std::atomic_int in_use;
+    // Track command buffers that this object is bound to
+    //  binding initialized when cmd referencing object is bound to command buffer
+    //  binding removed when command buffer is reset or destroyed
+    // When an object is destroyed, any bound cbs are set to INVALID
+    std::unordered_set<GLOBAL_CB_NODE *> cb_bindings;
+};
+
+// Generic wrapper for vulkan objects
+struct VK_OBJECT {
+    uint64_t handle;
+    VkDebugReportObjectTypeEXT type;
+};
+
+inline bool operator==(VK_OBJECT a, VK_OBJECT b) NOEXCEPT { return a.handle == b.handle && a.type == b.type; }
+
+namespace std {
+template <> struct hash<VK_OBJECT> {
+    size_t operator()(VK_OBJECT obj) const NOEXCEPT { return hash<uint64_t>()(obj.handle) ^ hash<uint32_t>()(obj.type); }
+};
+}
+
+
+// Flags describing requirements imposed by the pipeline on a descriptor. These
+// can't be checked at pipeline creation time as they depend on the Image or
+// ImageView bound.
+enum descriptor_req {
+    DESCRIPTOR_REQ_VIEW_TYPE_1D = 1 << VK_IMAGE_VIEW_TYPE_1D,
+    DESCRIPTOR_REQ_VIEW_TYPE_1D_ARRAY = 1 << VK_IMAGE_VIEW_TYPE_1D_ARRAY,
+    DESCRIPTOR_REQ_VIEW_TYPE_2D = 1 << VK_IMAGE_VIEW_TYPE_2D,
+    DESCRIPTOR_REQ_VIEW_TYPE_2D_ARRAY = 1 << VK_IMAGE_VIEW_TYPE_2D_ARRAY,
+    DESCRIPTOR_REQ_VIEW_TYPE_3D = 1 << VK_IMAGE_VIEW_TYPE_3D,
+    DESCRIPTOR_REQ_VIEW_TYPE_CUBE = 1 << VK_IMAGE_VIEW_TYPE_CUBE,
+    DESCRIPTOR_REQ_VIEW_TYPE_CUBE_ARRAY = 1 << VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,
+
+    DESCRIPTOR_REQ_SINGLE_SAMPLE = 2 << VK_IMAGE_VIEW_TYPE_END_RANGE,
+    DESCRIPTOR_REQ_MULTI_SAMPLE = DESCRIPTOR_REQ_SINGLE_SAMPLE << 1,
+};
+
+struct DESCRIPTOR_POOL_NODE {
+    VkDescriptorPool pool;
+    uint32_t maxSets;       // Max descriptor sets allowed in this pool
+    uint32_t availableSets; // Available descriptor sets in this pool
+
+    VkDescriptorPoolCreateInfo createInfo;
+    std::unordered_set<cvdescriptorset::DescriptorSet *> sets; // Collection of all sets in this pool
+    std::vector<uint32_t> maxDescriptorTypeCount;              // Max # of descriptors of each type in this pool
+    std::vector<uint32_t> availableDescriptorTypeCount;        // Available # of descriptors of each type in this pool
+
+    DESCRIPTOR_POOL_NODE(const VkDescriptorPool pool, const VkDescriptorPoolCreateInfo *pCreateInfo)
+        : pool(pool), maxSets(pCreateInfo->maxSets), availableSets(pCreateInfo->maxSets), createInfo(*pCreateInfo),
+          maxDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0), availableDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0) {
+        if (createInfo.poolSizeCount) { // Shadow type struct from ptr into local struct
+            size_t poolSizeCountSize = createInfo.poolSizeCount * sizeof(VkDescriptorPoolSize);
+            createInfo.pPoolSizes = new VkDescriptorPoolSize[poolSizeCountSize];
+            memcpy((void *)createInfo.pPoolSizes, pCreateInfo->pPoolSizes, poolSizeCountSize);
+            // Now set max counts for each descriptor type based on count of that type times maxSets
+            uint32_t i = 0;
+            for (i = 0; i < createInfo.poolSizeCount; ++i) {
+                uint32_t typeIndex = static_cast<uint32_t>(createInfo.pPoolSizes[i].type);
+                // Same descriptor types can appear several times
+                maxDescriptorTypeCount[typeIndex] += createInfo.pPoolSizes[i].descriptorCount;
+                availableDescriptorTypeCount[typeIndex] = maxDescriptorTypeCount[typeIndex];
+            }
+        } else {
+            createInfo.pPoolSizes = NULL; // Make sure this is NULL so we don't try to clean it up
+        }
+    }
+    ~DESCRIPTOR_POOL_NODE() {
+        delete[] createInfo.pPoolSizes;
+        // TODO : pSets are currently freed in deletePools function which uses freeShadowUpdateTree function
+        //  need to migrate that struct to smart ptrs for auto-cleanup
+    }
 };
 
 class BUFFER_NODE : public BASE_NODE {
   public:
     using BASE_NODE::in_use;
+    VkBuffer buffer;
     VkDeviceMemory mem;
+    VkDeviceSize memOffset;
+    VkDeviceSize memSize; // Note: may differ from createInfo::size
     VkBufferCreateInfo createInfo;
-    BUFFER_NODE() : mem(VK_NULL_HANDLE), createInfo{} { in_use.store(0); };
-    BUFFER_NODE(const VkBufferCreateInfo *pCreateInfo) : mem(VK_NULL_HANDLE), createInfo(*pCreateInfo) { in_use.store(0); };
-    BUFFER_NODE(const BUFFER_NODE &rh_obj) : mem(rh_obj.mem), createInfo(rh_obj.createInfo) { in_use.store(rh_obj.in_use.load()); };
+    BUFFER_NODE() : buffer(VK_NULL_HANDLE), mem(VK_NULL_HANDLE), memOffset(0), memSize(0), createInfo{} { in_use.store(0); };
+    BUFFER_NODE(VkBuffer buff, const VkBufferCreateInfo *pCreateInfo)
+        : buffer(buff), mem(VK_NULL_HANDLE), memOffset(0), memSize(0), createInfo(*pCreateInfo) {
+        in_use.store(0);
+    };
+    BUFFER_NODE(const BUFFER_NODE &rh_obj)
+        : buffer(rh_obj.buffer), mem(rh_obj.mem), memOffset(rh_obj.memOffset),
+          memSize(rh_obj.memSize), createInfo(rh_obj.createInfo) {
+        in_use.store(0);
+    };
 };
 
 struct SAMPLER_NODE {
@@ -82,24 +168,26 @@
 class IMAGE_NODE : public BASE_NODE {
   public:
     using BASE_NODE::in_use;
+    VkImage image;
     VkImageCreateInfo createInfo;
     VkDeviceMemory mem;
     bool valid; // If this is a swapchain image backing memory track valid here as it doesn't have DEVICE_MEM_INFO
     VkDeviceSize memOffset;
     VkDeviceSize memSize;
-    IMAGE_NODE() : createInfo{}, mem(VK_NULL_HANDLE), valid(false), memOffset(0), memSize(0) { in_use.store(0); };
-    IMAGE_NODE(const VkImageCreateInfo *pCreateInfo)
-        : createInfo(*pCreateInfo), mem(VK_NULL_HANDLE), valid(false), memOffset(0), memSize(0) {
+    IMAGE_NODE() : image(VK_NULL_HANDLE), createInfo{}, mem(VK_NULL_HANDLE), valid(false), memOffset(0), memSize(0) { in_use.store(0); };
+    IMAGE_NODE(VkImage img, const VkImageCreateInfo *pCreateInfo)
+        : image(img), createInfo(*pCreateInfo), mem(VK_NULL_HANDLE), valid(false), memOffset(0), memSize(0) {
         in_use.store(0);
     };
     IMAGE_NODE(const IMAGE_NODE &rh_obj)
-        : createInfo(rh_obj.createInfo), mem(rh_obj.mem), valid(rh_obj.valid), memOffset(rh_obj.memOffset),
+        : image(rh_obj.image), createInfo(rh_obj.createInfo), mem(rh_obj.mem), valid(rh_obj.valid), memOffset(rh_obj.memOffset),
           memSize(rh_obj.memSize) {
         in_use.store(rh_obj.in_use.load());
     };
 };
 
 // Simple struct to hold handle and type of object so they can be uniquely identified and looked up in appropriate map
+// TODO : Unify this with VK_OBJECT above
 struct MT_OBJ_HANDLE_TYPE {
     uint64_t handle;
     VkDebugReportObjectTypeEXT type;
@@ -128,16 +216,21 @@
 // Data struct for tracking memory object
 struct DEVICE_MEM_INFO {
     void *object; // Dispatchable object used to create this memory (device of swapchain)
-    bool valid;   // Stores if the memory has valid data or not
+    bool valid; // Stores if the color/depth/buffer memory has valid data or not
+    bool stencil_valid; // TODO: Stores if the stencil memory has valid data or not. The validity of this memory may ultimately need
+                        // to be tracked separately from the depth/stencil/buffer memory
     VkDeviceMemory mem;
-    VkMemoryAllocateInfo allocInfo;
-    std::unordered_set<MT_OBJ_HANDLE_TYPE> objBindings;        // objects bound to this memory
-    std::unordered_set<VkCommandBuffer> commandBufferBindings; // cmd buffers referencing this memory
-    std::vector<MEMORY_RANGE> bufferRanges;
-    std::vector<MEMORY_RANGE> imageRanges;
-    VkImage image; // If memory is bound to image, this will have VkImage handle, else VK_NULL_HANDLE
-    MemRange memRange;
-    void *pData, *pDriverData;
+    VkMemoryAllocateInfo alloc_info;
+    std::unordered_set<MT_OBJ_HANDLE_TYPE> obj_bindings;         // objects bound to this memory
+    std::unordered_set<VkCommandBuffer> command_buffer_bindings; // cmd buffers referencing this memory
+    std::vector<MEMORY_RANGE> buffer_ranges;
+    std::vector<MEMORY_RANGE> image_ranges;
+
+    MemRange mem_range;
+    void *p_data, *p_driver_data;
+    DEVICE_MEM_INFO(void *disp_object, const VkDeviceMemory in_mem, const VkMemoryAllocateInfo *p_alloc_info)
+        : object(disp_object), valid(false), stencil_valid(false), mem(in_mem), alloc_info(*p_alloc_info), mem_range{}, p_data(0),
+          p_driver_data(0){};
 };
 
 class SWAPCHAIN_NODE {
@@ -179,6 +272,8 @@
     uint32_t attachment;
     VkAttachmentLoadOp load_op;
     VkAttachmentStoreOp store_op;
+    VkAttachmentLoadOp stencil_load_op;
+    VkAttachmentStoreOp stencil_store_op;
 };
 
 // Store the DAG.
@@ -304,9 +399,9 @@
     CBSTATUS_STENCIL_READ_MASK_SET  = 0x00000020,   // Stencil read mask has been set
     CBSTATUS_STENCIL_WRITE_MASK_SET = 0x00000040,   // Stencil write mask has been set
     CBSTATUS_STENCIL_REFERENCE_SET  = 0x00000080,   // Stencil reference has been set
-    CBSTATUS_INDEX_BUFFER_BOUND     = 0x00000100,   // Index buffer has been set
-    CBSTATUS_SCISSOR_SET            = 0x00000200,   // Scissor has been set
-    CBSTATUS_ALL                    = 0x000003FF,   // All dynamic state set
+    CBSTATUS_SCISSOR_SET            = 0x00000100,   // Scissor has been set
+    CBSTATUS_INDEX_BUFFER_BOUND     = 0x00000200,   // Index buffer has been set
+    CBSTATUS_ALL                    = 0x000001FF,   // All dynamic state set (intentionally exclude index buffer)
     // clang-format on
 };
 
@@ -357,10 +452,25 @@
 };
 }
 
+// Store layouts and pushconstants for PipelineLayout
+struct PIPELINE_LAYOUT_NODE {
+    VkPipelineLayout layout;
+    std::vector<cvdescriptorset::DescriptorSetLayout const *> set_layouts;
+    std::vector<VkPushConstantRange> push_constant_ranges;
+
+    PIPELINE_LAYOUT_NODE() : layout(VK_NULL_HANDLE), set_layouts{}, push_constant_ranges{} {}
+
+    void reset() {
+        layout = VK_NULL_HANDLE;
+        set_layouts.clear();
+        push_constant_ranges.clear();
+    }
+};
+
 // Track last states that are bound per pipeline bind point (Gfx & Compute)
 struct LAST_BOUND_STATE {
     VkPipeline pipeline;
-    VkPipelineLayout pipelineLayout;
+    PIPELINE_LAYOUT_NODE pipeline_layout;
     // Track each set that has been bound
     // TODO : can unique be global per CB? (do we care about Gfx vs. Compute?)
     std::unordered_set<cvdescriptorset::DescriptorSet *> uniqueBoundSets;
@@ -371,7 +481,7 @@
 
     void reset() {
         pipeline = VK_NULL_HANDLE;
-        pipelineLayout = VK_NULL_HANDLE;
+        pipeline_layout.reset();
         uniqueBoundSets.clear();
         boundDescriptorSets.clear();
         dynamicOffsets.clear();
@@ -383,7 +493,6 @@
     VkCommandBufferAllocateInfo createInfo;
     VkCommandBufferBeginInfo beginInfo;
     VkCommandBufferInheritanceInfo inheritanceInfo;
-    // VkFence fence;                      // fence tracking this cmd buffer
     VkDevice device;                    // device this CB belongs to
     uint64_t numCmds;                   // number of cmds in this CB
     uint64_t drawCount[NUM_DRAW_TYPES]; // Count of each type of draw in this CB
@@ -397,27 +506,21 @@
     // Store last bound state for Gfx & Compute pipeline bind points
     LAST_BOUND_STATE lastBound[VK_PIPELINE_BIND_POINT_RANGE_SIZE];
 
-    std::vector<VkViewport> viewports;
-    std::vector<VkRect2D> scissors;
+    uint32_t viewportMask;
+    uint32_t scissorMask;
     VkRenderPassBeginInfo activeRenderPassBeginInfo;
-    uint64_t fenceId;
-    VkFence lastSubmittedFence;
-    VkQueue lastSubmittedQueue;
     RENDER_PASS_NODE *activeRenderPass;
     VkSubpassContents activeSubpassContents;
     uint32_t activeSubpass;
     VkFramebuffer activeFramebuffer;
     std::unordered_set<VkFramebuffer> framebuffers;
-    // Track descriptor sets that are destroyed or updated while bound to CB
-    // TODO : These data structures relate to tracking resources that invalidate
-    //  a cmd buffer that references them. Need to unify how we handle these
-    //  cases so we don't have different tracking data for each type.
-    std::unordered_set<cvdescriptorset::DescriptorSet *> destroyedSets;
-    std::unordered_set<cvdescriptorset::DescriptorSet *> updatedSets;
-    std::unordered_set<VkFramebuffer> destroyedFramebuffers;
+    // Unified data structs to track objects bound to this command buffer as well as object
+    //  dependencies that have been broken : either destroyed objects, or updated descriptor sets
+    std::unordered_set<VK_OBJECT> object_bindings;
+    std::vector<VK_OBJECT> broken_bindings;
+
     std::unordered_set<VkEvent> waitedEvents;
     std::vector<VkEvent> writeEventsBeforeWait;
-    std::vector<VkSemaphore> semaphores;
     std::vector<VkEvent> events;
     std::unordered_map<QueryObject, std::unordered_set<VkEvent>> waitedEventsBeforeQueryReset;
     std::unordered_map<QueryObject, bool> queryToStateMap; // 0 is unavailable, 1 is available
@@ -444,4 +547,30 @@
     ~GLOBAL_CB_NODE();
 };
 
+struct CB_SUBMISSION {
+    CB_SUBMISSION(std::vector<VkCommandBuffer> const &cbs, std::vector<VkSemaphore> const &semaphores)
+        : cbs(cbs), semaphores(semaphores) {}
+
+    std::vector<VkCommandBuffer> cbs;
+    std::vector<VkSemaphore> semaphores;
+};
+
+// Fwd declarations of layer_data and helpers to look-up/validate state from layer_data maps
+namespace core_validation {
+struct layer_data;
+cvdescriptorset::DescriptorSet *getSetNode(const layer_data *, VkDescriptorSet);
+cvdescriptorset::DescriptorSetLayout const *getDescriptorSetLayout(layer_data const *, VkDescriptorSetLayout);
+DESCRIPTOR_POOL_NODE *getPoolNode(const layer_data *, const VkDescriptorPool);
+BUFFER_NODE *getBufferNode(const layer_data *, VkBuffer);
+IMAGE_NODE *getImageNode(const layer_data *, VkImage);
+DEVICE_MEM_INFO *getMemObjInfo(const layer_data *, VkDeviceMemory);
+VkBufferViewCreateInfo *getBufferViewInfo(const layer_data *, VkBufferView);
+SAMPLER_NODE *getSamplerNode(const layer_data *, VkSampler);
+VkImageViewCreateInfo *getImageViewData(const layer_data *, VkImageView);
+VkSwapchainKHR getSwapchainFromImage(const layer_data *, VkImage);
+SWAPCHAIN_NODE *getSwapchainNode(const layer_data *, VkSwapchainKHR);
+void invalidateCommandBuffers(std::unordered_set<GLOBAL_CB_NODE *>, VK_OBJECT);
+bool ValidateMemoryIsBoundToBuffer(const layer_data *, const BUFFER_NODE *, const char *);
+}
+
 #endif // CORE_VALIDATION_TYPES_H_
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp
index 5fc1de3..21c2060 100644
--- a/layers/descriptor_sets.cpp
+++ b/layers/descriptor_sets.cpp
@@ -50,7 +50,7 @@
         }
         if (p_create_info->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
             p_create_info->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
-            dynamic_descriptor_count_++;
+            dynamic_descriptor_count_ += p_create_info->pBindings[i].descriptorCount;
         }
     }
 }
@@ -131,6 +131,7 @@
         return btgsi_itr->second;
     }
     // In error case max uint32_t so index is out of bounds to break ASAP
+    assert(0);
     return 0xFFFFFFFF;
 }
 // For the given binding, return end index
@@ -141,6 +142,7 @@
         return btgei_itr->second;
     }
     // In error case max uint32_t so index is out of bounds to break ASAP
+    assert(0);
     return 0xFFFFFFFF;
 }
 // For given binding, return ptr to ImmutableSampler array
@@ -260,18 +262,12 @@
     return true;
 }
 
+cvdescriptorset::AllocateDescriptorSetsData::AllocateDescriptorSetsData(uint32_t count)
+    : required_descriptors_by_type{}, layout_nodes(count, nullptr) {}
+
 cvdescriptorset::DescriptorSet::DescriptorSet(const VkDescriptorSet set, const DescriptorSetLayout *layout,
-                                              const std::unordered_map<VkBuffer, BUFFER_NODE> *buffer_map,
-                                              const std::unordered_map<VkDeviceMemory, DEVICE_MEM_INFO> *memory_map,
-                                              const std::unordered_map<VkBufferView, VkBufferViewCreateInfo> *buffer_view_map,
-                                              const std::unordered_map<VkSampler, std::unique_ptr<SAMPLER_NODE>> *sampler_map,
-                                              const std::unordered_map<VkImageView, VkImageViewCreateInfo> *image_view_map,
-                                              const std::unordered_map<VkImage, IMAGE_NODE> *image_map,
-                                              const std::unordered_map<VkImage, VkSwapchainKHR> *image_to_swapchain_map,
-                                              const std::unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> *swapchain_map)
-    : some_update_(false), set_(set), p_layout_(layout), buffer_map_(buffer_map), memory_map_(memory_map),
-      buffer_view_map_(buffer_view_map), sampler_map_(sampler_map), image_view_map_(image_view_map), image_map_(image_map),
-      image_to_swapchain_map_(image_to_swapchain_map), swapchain_map_(swapchain_map) {
+                                              const core_validation::layer_data *dev_data)
+    : some_update_(false), set_(set), p_layout_(layout), device_data_(dev_data) {
     // Foreach binding, create default descriptors of given type
     for (uint32_t i = 0; i < p_layout_->GetBindingCount(); ++i) {
         auto type = p_layout_->GetTypeFromIndex(i);
@@ -280,9 +276,9 @@
             auto immut_sampler = p_layout_->GetImmutableSamplerPtrFromIndex(i);
             for (uint32_t di = 0; di < p_layout_->GetDescriptorCountFromIndex(i); ++di) {
                 if (immut_sampler)
-                    descriptors_.emplace_back(std::unique_ptr<Descriptor>(new SamplerDescriptor(immut_sampler + di)));
+                    descriptors_.emplace_back(new SamplerDescriptor(immut_sampler + di));
                 else
-                    descriptors_.emplace_back(std::unique_ptr<Descriptor>(new SamplerDescriptor()));
+                    descriptors_.emplace_back(new SamplerDescriptor());
             }
             break;
         }
@@ -290,9 +286,9 @@
             auto immut = p_layout_->GetImmutableSamplerPtrFromIndex(i);
             for (uint32_t di = 0; di < p_layout_->GetDescriptorCountFromIndex(i); ++di) {
                 if (immut)
-                    descriptors_.emplace_back(std::unique_ptr<Descriptor>(new ImageSamplerDescriptor(immut + di)));
+                    descriptors_.emplace_back(new ImageSamplerDescriptor(immut + di));
                 else
-                    descriptors_.emplace_back(std::unique_ptr<Descriptor>(new ImageSamplerDescriptor()));
+                    descriptors_.emplace_back(new ImageSamplerDescriptor());
             }
             break;
         }
@@ -301,19 +297,19 @@
         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
             for (uint32_t di = 0; di < p_layout_->GetDescriptorCountFromIndex(i); ++di)
-                descriptors_.emplace_back(std::unique_ptr<Descriptor>(new ImageDescriptor(type)));
+                descriptors_.emplace_back(new ImageDescriptor(type));
             break;
         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
             for (uint32_t di = 0; di < p_layout_->GetDescriptorCountFromIndex(i); ++di)
-                descriptors_.emplace_back(std::unique_ptr<Descriptor>(new TexelDescriptor(type)));
+                descriptors_.emplace_back(new TexelDescriptor(type));
             break;
         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
             for (uint32_t di = 0; di < p_layout_->GetDescriptorCountFromIndex(i); ++di)
-                descriptors_.emplace_back(std::unique_ptr<Descriptor>(new BufferDescriptor(type)));
+                descriptors_.emplace_back(new BufferDescriptor(type));
             break;
         default:
             assert(0); // Bad descriptor type specified
@@ -325,29 +321,51 @@
 cvdescriptorset::DescriptorSet::~DescriptorSet() {
     InvalidateBoundCmdBuffers();
     // Remove link to any cmd buffers
-    for (auto cb : bound_cmd_buffers_) {
+    for (auto cb : cb_bindings) {
         for (uint32_t i=0; i<VK_PIPELINE_BIND_POINT_RANGE_SIZE; ++i) {
             cb->lastBound[i].uniqueBoundSets.erase(this);
         }
     }
 }
+
+
+static char const * string_descriptor_req_view_type(descriptor_req req) {
+    for (unsigned i = 0; i <= VK_IMAGE_VIEW_TYPE_END_RANGE; i++) {
+        if (req & (1 << i)) {
+            return string_VkImageViewType(VkImageViewType(i));
+        }
+    }
+
+    return "(none)";
+}
+
+
 // Is this sets underlying layout compatible with passed in layout according to "Pipeline Layout Compatibility" in spec?
 bool cvdescriptorset::DescriptorSet::IsCompatible(const DescriptorSetLayout *layout, std::string *error) const {
     return layout->IsCompatible(p_layout_, error);
 }
+
 // Validate that the state of this set is appropriate for the given bindings and dynami_offsets at Draw time
 //  This includes validating that all descriptors in the given bindings are updated,
 //  that any update buffers are valid, and that any dynamic offsets are within the bounds of their buffers.
 // Return true if state is acceptable, or false and write an error message into error string
-bool cvdescriptorset::DescriptorSet::ValidateDrawState(const std::unordered_set<uint32_t> &bindings,
+bool cvdescriptorset::DescriptorSet::ValidateDrawState(const std::unordered_map<uint32_t, descriptor_req> &bindings,
                                                        const std::vector<uint32_t> &dynamic_offsets, std::string *error) const {
-    for (auto binding : bindings) {
+    auto dyn_offset_index = 0;
+    for (auto binding_pair : bindings) {
+        auto binding = binding_pair.first;
+        if (!p_layout_->HasBinding(binding)) {
+            std::stringstream error_str;
+            error_str << "Attempting to validate DrawState for binding #" << binding
+                      << " which is an invalid binding for this descriptor set.";
+            *error = error_str.str();
+            return false;
+        }
         auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(binding);
         if (descriptors_[start_idx]->IsImmutableSampler()) {
             // Nothing to do for strictly immutable sampler
         } else {
             auto end_idx = p_layout_->GetGlobalEndIndexFromBinding(binding);
-            auto dyn_offset_index = 0;
             for (uint32_t i = start_idx; i <= end_idx; ++i) {
                 if (!descriptors_[i]->updated) {
                     std::stringstream error_str;
@@ -356,30 +374,31 @@
                     *error = error_str.str();
                     return false;
                 } else {
-                    if (GeneralBuffer == descriptors_[i]->GetClass()) {
+                    auto descriptor_class = descriptors_[i]->GetClass();
+                    if (descriptor_class == GeneralBuffer) {
                         // Verify that buffers are valid
                         auto buffer = static_cast<BufferDescriptor *>(descriptors_[i].get())->GetBuffer();
-                        auto buffer_node = buffer_map_->find(buffer);
-                        if (buffer_node == buffer_map_->end()) {
+                        auto buffer_node = getBufferNode(device_data_, buffer);
+                        if (!buffer_node) {
                             std::stringstream error_str;
                             error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
                                       << " references invalid buffer " << buffer << ".";
                             *error = error_str.str();
                             return false;
                         } else {
-                            auto mem_entry = memory_map_->find(buffer_node->second.mem);
-                            if (mem_entry == memory_map_->end()) {
+                            auto mem_entry = getMemObjInfo(device_data_, buffer_node->mem);
+                            if (!mem_entry) {
                                 std::stringstream error_str;
                                 error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
-                                          << " uses buffer " << buffer << " that references invalid memory "
-                                          << buffer_node->second.mem << ".";
+                                          << " uses buffer " << buffer << " that references invalid memory " << buffer_node->mem
+                                          << ".";
                                 *error = error_str.str();
                                 return false;
                             }
                         }
                         if (descriptors_[i]->IsDynamic()) {
                             // Validate that dynamic offsets are within the buffer
-                            auto buffer_size = buffer_node->second.createInfo.size;
+                            auto buffer_size = buffer_node->createInfo.size;
                             auto range = static_cast<BufferDescriptor *>(descriptors_[i].get())->GetRange();
                             auto desc_offset = static_cast<BufferDescriptor *>(descriptors_[i].get())->GetOffset();
                             auto dyn_offset = dynamic_offsets[dyn_offset_index++];
@@ -407,18 +426,65 @@
                             }
                         }
                     }
+                    else if (descriptor_class == ImageSampler || descriptor_class == Image) {
+                        auto image_view = (descriptor_class == ImageSampler)
+                                ? static_cast<ImageSamplerDescriptor *>(descriptors_[i].get())->GetImageView()
+                                : static_cast<ImageDescriptor *>(descriptors_[i].get())->GetImageView();
+                        auto reqs = binding_pair.second;
+
+                        auto image_view_data = getImageViewData(device_data_, image_view);
+                        assert(image_view_data);
+
+                        if (~reqs & (1 << image_view_data->viewType)) {
+                            // bad view type
+                            std::stringstream error_str;
+                            error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
+                                      << " requires an image view of type " << string_descriptor_req_view_type(reqs)
+                                      << " but got " << string_VkImageViewType(image_view_data->viewType) << ".";
+                            *error = error_str.str();
+                            return false;
+                        }
+
+                        auto image_node = getImageNode(device_data_, image_view_data->image);
+                        assert(image_node);
+
+                        if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) &&
+                            image_node->createInfo.samples != VK_SAMPLE_COUNT_1_BIT) {
+                            std::stringstream error_str;
+                            error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
+                                      << " requires bound image to have VK_SAMPLE_COUNT_1_BIT but got "
+                                      << string_VkSampleCountFlagBits(image_node->createInfo.samples) << ".";
+                            *error = error_str.str();
+                            return false;
+                        }
+
+                        if ((reqs & DESCRIPTOR_REQ_MULTI_SAMPLE) &&
+                            image_node->createInfo.samples == VK_SAMPLE_COUNT_1_BIT) {
+                            std::stringstream error_str;
+                            error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
+                                      << " requires bound image to have multiple samples, but got VK_SAMPLE_COUNT_1_BIT.";
+                            *error = error_str.str();
+                            return false;
+                        }
+                    }
                 }
             }
         }
     }
     return true;
 }
+
 // For given bindings, place any update buffers or images into the passed-in unordered_sets
-uint32_t cvdescriptorset::DescriptorSet::GetStorageUpdates(const std::unordered_set<uint32_t> &bindings,
+uint32_t cvdescriptorset::DescriptorSet::GetStorageUpdates(const std::unordered_map<uint32_t, descriptor_req> &bindings,
                                                            std::unordered_set<VkBuffer> *buffer_set,
                                                            std::unordered_set<VkImageView> *image_set) const {
     auto num_updates = 0;
-    for (auto binding : bindings) {
+    for (auto binding_pair : bindings) {
+        auto binding = binding_pair.first;
+        // If a binding doesn't exist, skip it
+        if (!p_layout_->HasBinding(binding)) {
+            continue;
+        }
         auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(binding);
         if (descriptors_[start_idx]->IsStorage()) {
             if (Image == descriptors_[start_idx]->descriptor_class) {
@@ -432,9 +498,9 @@
                 for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) {
                     if (descriptors_[start_idx + i]->updated) {
                         auto bufferview = static_cast<TexelDescriptor *>(descriptors_[start_idx + i].get())->GetBufferView();
-                        const auto &buff_pair = buffer_view_map_->find(bufferview);
-                        if (buff_pair != buffer_view_map_->end()) {
-                            buffer_set->insert(buff_pair->second.buffer);
+                        auto bv_info = getBufferViewInfo(device_data_, bufferview);
+                        if (bv_info) {
+                            buffer_set->insert(bv_info->buffer);
                             num_updates++;
                         }
                     }
@@ -451,19 +517,10 @@
     }
     return num_updates;
 }
-// This is a special case for compute shaders that should eventually be removed once we have proper valid binding info for compute
-// case
-uint32_t cvdescriptorset::DescriptorSet::GetAllStorageUpdates(std::unordered_set<VkBuffer> *buffer_set,
-                                                              std::unordered_set<VkImageView> *image_set) const {
-    std::unordered_set<uint32_t> binding_set;
-    p_layout_->FillBindingSet(&binding_set);
-    return GetStorageUpdates(binding_set, buffer_set, image_set);
-}
 // Set is being deleted or updates so invalidate all bound cmd buffers
 void cvdescriptorset::DescriptorSet::InvalidateBoundCmdBuffers() {
-    for (auto cb_node : bound_cmd_buffers_) {
-        cb_node->state = CB_INVALID;
-    }
+    core_validation::invalidateCommandBuffers(cb_bindings,
+                                              {reinterpret_cast<uint64_t &>(set_), VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT});
 }
 // Perform write update in given update struct
 void cvdescriptorset::DescriptorSet::PerformWriteUpdate(const VkWriteDescriptorSet *update) {
@@ -553,7 +610,7 @@
         }
     }
     // Update parameters all look good and descriptor updated so verify update contents
-    if (!VerifyCopyUpdateContents(update, src_set, src_start_idx, error))
+    if (!VerifyCopyUpdateContents(update, src_set, src_type, src_start_idx, error))
         return false;
 
     // All checks passed so update is good
@@ -587,103 +644,150 @@
         updated = true;
     }
 }
-
-bool cvdescriptorset::ValidateSampler(const VkSampler sampler,
-                                      const std::unordered_map<VkSampler, std::unique_ptr<SAMPLER_NODE>> *sampler_map) {
-    return (sampler_map->count(sampler) != 0);
+// Validate given sampler. Currently this only checks to make sure it exists in the samplerMap
+bool cvdescriptorset::ValidateSampler(const VkSampler sampler, const core_validation::layer_data *dev_data) {
+    return (getSamplerNode(dev_data, sampler) != nullptr);
 }
 
-bool cvdescriptorset::ValidateImageUpdate(const VkImageView image_view, const VkImageLayout image_layout,
-                                          const std::unordered_map<VkImageView, VkImageViewCreateInfo> *image_view_map,
-                                          const std::unordered_map<VkImage, IMAGE_NODE> *image_map,
-                                          const std::unordered_map<VkImage, VkSwapchainKHR> *image_to_swapchain_map,
-                                          const std::unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> *swapchain_map,
+bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout image_layout, VkDescriptorType type,
+                                          const core_validation::layer_data *dev_data,
                                           std::string *error) {
-    auto image_pair = image_view_map->find(image_view);
-    if (image_pair == image_view_map->end()) {
+    auto iv_data = getImageViewData(dev_data, image_view);
+    if (!iv_data) {
         std::stringstream error_str;
         error_str << "Invalid VkImageView: " << image_view;
         *error = error_str.str();
         return false;
+    }
+    // Note that when an imageview is created, we validated that memory is bound so no need to re-check here
+    // Validate that imageLayout is compatible with aspect_mask and image format
+    //  and validate that image usage bits are correct for given usage
+    VkImageAspectFlags aspect_mask = iv_data->subresourceRange.aspectMask;
+    VkImage image = iv_data->image;
+    VkFormat format = VK_FORMAT_MAX_ENUM;
+    VkImageUsageFlags usage = 0;
+    auto image_node = getImageNode(dev_data, image);
+    if (image_node) {
+        format = image_node->createInfo.format;
+        usage = image_node->createInfo.usage;
     } else {
-        // Validate that imageLayout is compatible with aspect_mask and image format
-        VkImageAspectFlags aspect_mask = image_pair->second.subresourceRange.aspectMask;
-        VkImage image = image_pair->second.image;
-        VkFormat format = VK_FORMAT_MAX_ENUM;
-        auto img_pair = image_map->find(image);
-        if (img_pair != image_map->end()) {
-            format = img_pair->second.createInfo.format;
-        } else {
-            // Also need to check the swapchains.
-            auto swapchain_pair = image_to_swapchain_map->find(image);
-            if (swapchain_pair != image_to_swapchain_map->end()) {
-                VkSwapchainKHR swapchain = swapchain_pair->second;
-                auto swapchain_pair = swapchain_map->find(swapchain);
-                if (swapchain_pair != swapchain_map->end()) {
-                    format = swapchain_pair->second->createInfo.imageFormat;
-                }
+        // Also need to check the swapchains.
+        auto swapchain = getSwapchainFromImage(dev_data, image);
+        if (swapchain) {
+            auto swapchain_node = getSwapchainNode(dev_data, swapchain);
+            if (swapchain_node) {
+                format = swapchain_node->createInfo.imageFormat;
             }
         }
-        if (format == VK_FORMAT_MAX_ENUM) {
+    }
+    // First validate that format and layout are compatible
+    if (format == VK_FORMAT_MAX_ENUM) {
+        std::stringstream error_str;
+        error_str << "Invalid image (" << image << ") in imageView (" << image_view << ").";
+        *error = error_str.str();
+        return false;
+    }
+    bool ds = vk_format_is_depth_or_stencil(format);
+    switch (image_layout) {
+    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
+        // Only Color bit must be set
+        if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
             std::stringstream error_str;
-            error_str << "Invalid image (" << image << ") in imageView (" << image_view << ").";
+            error_str << "ImageView (" << image_view << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but does "
+                                                        "not have VK_IMAGE_ASPECT_COLOR_BIT set.";
             *error = error_str.str();
             return false;
-        } else {
-            bool ds = vk_format_is_depth_or_stencil(format);
-            switch (image_layout) {
-            case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
-                // Only Color bit must be set
-                if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
-                    std::stringstream error_str;
-                    error_str << "ImageView (" << image_view << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but does "
-                                                                "not have VK_IMAGE_ASPECT_COLOR_BIT set.";
-                    *error = error_str.str();
-                    return false;
-                }
-                // format must NOT be DS
-                if (ds) {
-                    std::stringstream error_str;
-                    error_str << "ImageView (" << image_view
-                              << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but the image format is "
-                              << string_VkFormat(format) << " which is not a color format.";
-                    *error = error_str.str();
-                    return false;
-                }
-                break;
-            case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
-            case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
-                // Depth or stencil bit must be set, but both must NOT be set
-                if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
-                    if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
-                        // both  must NOT be set
-                        std::stringstream error_str;
-                        error_str << "ImageView (" << image_view << ") has both STENCIL and DEPTH aspects set";
-                        *error = error_str.str();
-                        return false;
-                    }
-                } else if (!(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
-                    // Neither were set
+        }
+        // format must NOT be DS
+        if (ds) {
+            std::stringstream error_str;
+            error_str << "ImageView (" << image_view
+                      << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but the image format is "
+                      << string_VkFormat(format) << " which is not a color format.";
+            *error = error_str.str();
+            return false;
+        }
+        break;
+    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
+    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
+        // Depth or stencil bit must be set, but both must NOT be set
+        if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
+            if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
+                // both  must NOT be set
+                std::stringstream error_str;
+                error_str << "ImageView (" << image_view << ") has both STENCIL and DEPTH aspects set";
+                *error = error_str.str();
+                return false;
+            }
+        } else if (!(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
+            // Neither were set
+            std::stringstream error_str;
+            error_str << "ImageView (" << image_view << ") has layout " << string_VkImageLayout(image_layout)
+                      << " but does not have STENCIL or DEPTH aspects set";
+            *error = error_str.str();
+            return false;
+        }
+        // format must be DS
+        if (!ds) {
+            std::stringstream error_str;
+            error_str << "ImageView (" << image_view << ") has layout " << string_VkImageLayout(image_layout)
+                      << " but the image format is " << string_VkFormat(format) << " which is not a depth/stencil format.";
+            *error = error_str.str();
+            return false;
+        }
+        break;
+    default:
+        // For other layouts if the source is ds image, both aspect bits must not be set
+        if (ds) {
+            if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
+                if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
+                    // both  must NOT be set
                     std::stringstream error_str;
                     error_str << "ImageView (" << image_view << ") has layout " << string_VkImageLayout(image_layout)
-                              << " but does not have STENCIL or DEPTH aspects set";
+                              << " and is using depth/stencil image of format " << string_VkFormat(format)
+                              << " but it has both STENCIL and DEPTH aspects set, which is illegal. When using a depth/stencil "
+                                 "image in a descriptor set, please only set either VK_IMAGE_ASPECT_DEPTH_BIT or "
+                                 "VK_IMAGE_ASPECT_STENCIL_BIT depending on whether it will be used for depth reads or stencil "
+                                 "reads respectively.";
                     *error = error_str.str();
                     return false;
                 }
-                // format must be DS
-                if (!ds) {
-                    std::stringstream error_str;
-                    error_str << "ImageView (" << image_view << ") has layout " << string_VkImageLayout(image_layout)
-                              << " but the image format is " << string_VkFormat(format) << " which is not a depth/stencil format.";
-                    *error = error_str.str();
-                    return false;
-                }
-                break;
-            default:
-                // anything to check for other layouts?
-                break;
             }
         }
+        break;
+    }
+    // Now validate that usage flags are correctly set for given type of update
+    std::string error_usage_bit;
+    switch (type) {
+    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
+        if (!(usage & VK_IMAGE_USAGE_SAMPLED_BIT)) {
+            error_usage_bit = "VK_IMAGE_USAGE_SAMPLED_BIT";
+        }
+        break;
+    }
+    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
+        if (!(usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
+            error_usage_bit = "VK_IMAGE_USAGE_STORAGE_BIT";
+        }
+        break;
+    }
+    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
+        if (!(usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
+            error_usage_bit = "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT";
+        }
+        break;
+    }
+    default:
+        break;
+    }
+    if (!error_usage_bit.empty()) {
+        std::stringstream error_str;
+        error_str << "ImageView (" << image_view << ") with usage mask 0x" << usage
+                  << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
+                  << error_usage_bit << " set.";
+        *error = error_str.str();
+        return false;
     }
     return true;
 }
@@ -811,15 +915,16 @@
 // If the update hits an issue for which the callback returns "true", meaning that the call down the chain should
 //  be skipped, then true is returned.
 // If there is no issue with the update, then false is returned.
-bool cvdescriptorset::ValidateUpdateDescriptorSets(
-    const debug_report_data *report_data, const std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> &set_map,
-    uint32_t write_count, const VkWriteDescriptorSet *p_wds, uint32_t copy_count, const VkCopyDescriptorSet *p_cds) {
+bool cvdescriptorset::ValidateUpdateDescriptorSets(const debug_report_data *report_data,
+                                                   const core_validation::layer_data *dev_data, uint32_t write_count,
+                                                   const VkWriteDescriptorSet *p_wds, uint32_t copy_count,
+                                                   const VkCopyDescriptorSet *p_cds) {
     bool skip_call = false;
     // Validate Write updates
     for (uint32_t i = 0; i < write_count; i++) {
         auto dest_set = p_wds[i].dstSet;
-        auto set_pair = set_map.find(dest_set);
-        if (set_pair == set_map.end()) {
+        auto set_node = core_validation::getSetNode(dev_data, dest_set);
+        if (!set_node) {
             skip_call |=
                 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                         reinterpret_cast<uint64_t &>(dest_set), __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS",
@@ -827,9 +932,9 @@
                         reinterpret_cast<uint64_t &>(dest_set));
         } else {
             std::string error_str;
-            if (!set_pair->second->ValidateWriteUpdate(report_data, &p_wds[i], &error_str)) {
+            if (!set_node->ValidateWriteUpdate(report_data, &p_wds[i], &error_str)) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                                     reinterpret_cast<uint64_t &>(dest_set), __LINE__, DRAWSTATE_INVALID_UPDATE_INDEX, "DS",
+                                     reinterpret_cast<uint64_t &>(dest_set), __LINE__, DRAWSTATE_INVALID_WRITE_UPDATE, "DS",
                                      "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x%" PRIx64
                                      " with error: %s",
                                      reinterpret_cast<uint64_t &>(dest_set), error_str.c_str());
@@ -840,15 +945,15 @@
     for (uint32_t i = 0; i < copy_count; ++i) {
         auto dst_set = p_cds[i].dstSet;
         auto src_set = p_cds[i].srcSet;
-        auto src_pair = set_map.find(src_set);
-        auto dst_pair = set_map.find(dst_set);
-        if (src_pair == set_map.end()) {
+        auto src_node = core_validation::getSetNode(dev_data, src_set);
+        auto dst_node = core_validation::getSetNode(dev_data, dst_set);
+        if (!src_node) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                                  reinterpret_cast<uint64_t &>(src_set), __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS",
                                  "Cannot call vkUpdateDescriptorSets() to copy from descriptor set 0x%" PRIxLEAST64
                                  " that has not been allocated.",
                                  reinterpret_cast<uint64_t &>(src_set));
-        } else if (dst_pair == set_map.end()) {
+        } else if (!dst_node) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                                  reinterpret_cast<uint64_t &>(dst_set), __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS",
                                  "Cannot call vkUpdateDescriptorSets() to copy to descriptor set 0x%" PRIxLEAST64
@@ -856,10 +961,10 @@
                                  reinterpret_cast<uint64_t &>(dst_set));
         } else {
             std::string error_str;
-            if (!dst_pair->second->ValidateCopyUpdate(report_data, &p_cds[i], src_pair->second, &error_str)) {
+            if (!dst_node->ValidateCopyUpdate(report_data, &p_cds[i], src_node, &error_str)) {
                 skip_call |=
                     log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                            reinterpret_cast<uint64_t &>(dst_set), __LINE__, DRAWSTATE_INVALID_UPDATE_INDEX, "DS",
+                            reinterpret_cast<uint64_t &>(dst_set), __LINE__, DRAWSTATE_INVALID_COPY_UPDATE, "DS",
                             "vkUpdateDescriptorsSets() failed copy update from Descriptor Set 0x%" PRIx64
                             " to Descriptor Set 0x%" PRIx64 " with error: %s",
                             reinterpret_cast<uint64_t &>(src_set), reinterpret_cast<uint64_t &>(dst_set), error_str.c_str());
@@ -874,26 +979,26 @@
 //  with the same set of updates.
 // This is split from the validate code to allow validation prior to calling down the chain, and then update after
 //  calling down the chain.
-void cvdescriptorset::PerformUpdateDescriptorSets(
-    const std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> &set_map, uint32_t write_count,
-    const VkWriteDescriptorSet *p_wds, uint32_t copy_count, const VkCopyDescriptorSet *p_cds) {
+void cvdescriptorset::PerformUpdateDescriptorSets(const core_validation::layer_data *dev_data, uint32_t write_count,
+                                                  const VkWriteDescriptorSet *p_wds, uint32_t copy_count,
+                                                  const VkCopyDescriptorSet *p_cds) {
     // Write updates first
     uint32_t i = 0;
     for (i = 0; i < write_count; ++i) {
         auto dest_set = p_wds[i].dstSet;
-        auto set_pair = set_map.find(dest_set);
-        if (set_pair != set_map.end()) {
-            set_pair->second->PerformWriteUpdate(&p_wds[i]);
+        auto set_node = core_validation::getSetNode(dev_data, dest_set);
+        if (set_node) {
+            set_node->PerformWriteUpdate(&p_wds[i]);
         }
     }
     // Now copy updates
     for (i = 0; i < copy_count; ++i) {
         auto dst_set = p_cds[i].dstSet;
         auto src_set = p_cds[i].srcSet;
-        auto src_pair = set_map.find(src_set);
-        auto dst_pair = set_map.find(dst_set);
-        if (src_pair != set_map.end() && dst_pair != set_map.end()) {
-            dst_pair->second->PerformCopyUpdate(&p_cds[i], src_pair->second);
+        auto src_node = core_validation::getSetNode(dev_data, src_set);
+        auto dst_node = core_validation::getSetNode(dev_data, dst_set);
+        if (src_node && dst_node) {
+            dst_node->PerformCopyUpdate(&p_cds[i], src_node);
         }
     }
 }
@@ -915,44 +1020,136 @@
         error_str << "DescriptorSet " << set_ << " does not have binding " << update->dstBinding << ".";
         *error_msg = error_str.str();
         return false;
-    } else {
-        // We know that binding is valid, verify update and do update on each descriptor
-        auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding) + update->dstArrayElement;
-        auto type = p_layout_->GetTypeFromBinding(update->dstBinding);
-        if (type != update->descriptorType) {
-            std::stringstream error_str;
-            error_str << "Attempting write update to descriptor set " << set_ << " binding #" << update->dstBinding << " with type "
-                      << string_VkDescriptorType(type) << " but update type is " << string_VkDescriptorType(update->descriptorType);
-            *error_msg = error_str.str();
-            return false;
-        }
-        if ((start_idx + update->descriptorCount) > p_layout_->GetTotalDescriptorCount()) {
-            std::stringstream error_str;
-            error_str << "Attempting write update to descriptor set " << set_ << " binding #" << update->dstBinding << " with "
-                      << p_layout_->GetTotalDescriptorCount() << " total descriptors but update of " << update->descriptorCount
-                      << " descriptors starting at binding offset of "
-                      << p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding)
-                      << " combined with update array element offset of " << update->dstArrayElement
-                      << " oversteps the size of this descriptor set.";
-            *error_msg = error_str.str();
-            return false;
-        }
-        // Verify consecutive bindings match (if needed)
-        if (!p_layout_->VerifyUpdateConsistency(update->dstBinding, update->dstArrayElement, update->descriptorCount,
-                                                "write update to", set_, error_msg))
-            return false;
-        // Update is within bounds and consistent so last step is to validate update contents
-        if (!VerifyWriteUpdateContents(update, start_idx, error_msg)) {
-            std::stringstream error_str;
-            error_str << "Write update to descriptor in set " << set_ << " binding #" << update->dstBinding
-                      << " failed with error message: " << error_msg->c_str();
-            *error_msg = error_str.str();
-            return false;
-        }
+    }
+    // We know that binding is valid, verify update and do update on each descriptor
+    auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding) + update->dstArrayElement;
+    auto type = p_layout_->GetTypeFromBinding(update->dstBinding);
+    if (type != update->descriptorType) {
+        std::stringstream error_str;
+        error_str << "Attempting write update to descriptor set " << set_ << " binding #" << update->dstBinding << " with type "
+                  << string_VkDescriptorType(type) << " but update type is " << string_VkDescriptorType(update->descriptorType);
+        *error_msg = error_str.str();
+        return false;
+    }
+    if ((start_idx + update->descriptorCount) > p_layout_->GetTotalDescriptorCount()) {
+        std::stringstream error_str;
+        error_str << "Attempting write update to descriptor set " << set_ << " binding #" << update->dstBinding << " with "
+                  << p_layout_->GetTotalDescriptorCount() << " total descriptors but update of " << update->descriptorCount
+                  << " descriptors starting at binding offset of " << p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding)
+                  << " combined with update array element offset of " << update->dstArrayElement
+                  << " oversteps the size of this descriptor set.";
+        *error_msg = error_str.str();
+        return false;
+    }
+    // Verify consecutive bindings match (if needed)
+    if (!p_layout_->VerifyUpdateConsistency(update->dstBinding, update->dstArrayElement, update->descriptorCount, "write update to",
+                                            set_, error_msg))
+        return false;
+    // Update is within bounds and consistent so last step is to validate update contents
+    if (!VerifyWriteUpdateContents(update, start_idx, error_msg)) {
+        std::stringstream error_str;
+        error_str << "Write update to descriptor in set " << set_ << " binding #" << update->dstBinding
+                  << " failed with error message: " << error_msg->c_str();
+        *error_msg = error_str.str();
+        return false;
     }
     // All checks passed, update is clean
     return true;
 }
+// For the given buffer, verify that its creation parameters are appropriate for the given type
+//  If there's an error, update the error string with details and return false, else return true
+bool cvdescriptorset::DescriptorSet::ValidateBufferUsage(BUFFER_NODE const *buffer_node, VkDescriptorType type,
+                                                         std::string *error) const {
+    // Verify that usage bits set correctly for given type
+    auto usage = buffer_node->createInfo.usage;
+    std::string error_usage_bit;
+    switch (type) {
+    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+        if (!(usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
+            error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT";
+        }
+        break;
+    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+        if (!(usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
+            error_usage_bit = "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT";
+        }
+        break;
+    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+        if (!(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
+            error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT";
+        }
+        break;
+    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+        if (!(usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
+            error_usage_bit = "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT";
+        }
+        break;
+    default:
+        break;
+    }
+    if (!error_usage_bit.empty()) {
+        std::stringstream error_str;
+        error_str << "Buffer (" << buffer_node->buffer << ") with usage mask 0x" << usage
+                  << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
+                  << error_usage_bit << " set.";
+        *error = error_str.str();
+        return false;
+    }
+    return true;
+}
+// For buffer descriptor updates, verify the buffer usage and VkDescriptorBufferInfo struct which includes:
+//  1. buffer is valid
+//  2. buffer was created with correct usage flags
+//  3. offset is less than buffer size
+//  4. range is either VK_WHOLE_SIZE or falls in (0, (buffer size - offset)]
+// If there's an error, update the error string with details and return false, else return true
+bool cvdescriptorset::DescriptorSet::ValidateBufferUpdate(VkDescriptorBufferInfo const *buffer_info, VkDescriptorType type,
+                                                          std::string *error) const {
+    // First make sure that buffer is valid
+    auto buffer_node = getBufferNode(device_data_, buffer_info->buffer);
+    if (!buffer_node) {
+        std::stringstream error_str;
+        error_str << "Invalid VkBuffer: " << buffer_info->buffer;
+        *error = error_str.str();
+        return false;
+    }
+    if (ValidateMemoryIsBoundToBuffer(device_data_, buffer_node, "vkUpdateDescriptorSets()"))
+        return false;
+    // Verify usage bits
+    if (!ValidateBufferUsage(buffer_node, type, error)) {
+        // error will have been updated by ValidateBufferUsage()
+        return false;
+    }
+    // offset must be less than buffer size
+    if (buffer_info->offset > buffer_node->createInfo.size) {
+        std::stringstream error_str;
+        error_str << "VkDescriptorBufferInfo offset of " << buffer_info->offset << " is greater than buffer " << buffer_node->buffer
+                  << " size of " << buffer_node->createInfo.size;
+        *error = error_str.str();
+        return false;
+    }
+    if (buffer_info->range != VK_WHOLE_SIZE) {
+        // Range must be VK_WHOLE_SIZE or > 0
+        if (!buffer_info->range) {
+            std::stringstream error_str;
+            error_str << "VkDescriptorBufferInfo range is not VK_WHOLE_SIZE and is zero, which is not allowed.";
+            *error = error_str.str();
+            return false;
+        }
+        // Range must be VK_WHOLE_SIZE or <= (buffer size - offset)
+        if (buffer_info->range > (buffer_node->createInfo.size - buffer_info->offset)) {
+            std::stringstream error_str;
+            error_str << "VkDescriptorBufferInfo range is " << buffer_info->range << " which is greater than buffer size ("
+                      << buffer_node->createInfo.size << ") minus requested offset of " << buffer_info->offset;
+            *error = error_str.str();
+            return false;
+        }
+    }
+    return true;
+}
+
 // Verify that the contents of the update are ok, but don't perform actual update
 bool cvdescriptorset::DescriptorSet::VerifyWriteUpdateContents(const VkWriteDescriptorSet *update, const uint32_t index,
                                                                std::string *error) const {
@@ -962,8 +1159,7 @@
             // Validate image
             auto image_view = update->pImageInfo[di].imageView;
             auto image_layout = update->pImageInfo[di].imageLayout;
-            if (!ValidateImageUpdate(image_view, image_layout, image_view_map_, image_map_, image_to_swapchain_map_, swapchain_map_,
-                                     error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error)) {
                 std::stringstream error_str;
                 error_str << "Attempted write update to combined image sampler descriptor failed due to: " << error->c_str();
                 *error = error_str.str();
@@ -975,7 +1171,7 @@
     case VK_DESCRIPTOR_TYPE_SAMPLER: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             if (!descriptors_[index + di].get()->IsImmutableSampler()) {
-                if (!ValidateSampler(update->pImageInfo[di].sampler, sampler_map_)) {
+                if (!ValidateSampler(update->pImageInfo[di].sampler, device_data_)) {
                     std::stringstream error_str;
                     error_str << "Attempted write update to sampler descriptor with invalid sampler: "
                               << update->pImageInfo[di].sampler << ".";
@@ -994,8 +1190,7 @@
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto image_view = update->pImageInfo[di].imageView;
             auto image_layout = update->pImageInfo[di].imageLayout;
-            if (!ValidateImageUpdate(image_view, image_layout, image_view_map_, image_map_, image_to_swapchain_map_, swapchain_map_,
-                                     error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error)) {
                 std::stringstream error_str;
                 error_str << "Attempted write update to image descriptor failed due to: " << error->c_str();
                 *error = error_str.str();
@@ -1008,12 +1203,20 @@
     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto buffer_view = update->pTexelBufferView[di];
-            if (!buffer_view_map_->count(buffer_view)) {
+            auto bv_info = getBufferViewInfo(device_data_, buffer_view);
+            if (!bv_info) {
                 std::stringstream error_str;
                 error_str << "Attempted write update to texel buffer descriptor with invalid buffer view: " << buffer_view;
                 *error = error_str.str();
                 return false;
             }
+            auto buffer = bv_info->buffer;
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), update->descriptorType, error)) {
+                std::stringstream error_str;
+                error_str << "Attempted write update to texel buffer descriptor failed due to: " << error->c_str();
+                *error = error_str.str();
+                return false;
+            }
         }
         break;
     }
@@ -1022,10 +1225,9 @@
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
-            auto buffer = update->pBufferInfo[di].buffer;
-            if (!buffer_map_->count(buffer)) {
+            if (!ValidateBufferUpdate(update->pBufferInfo + di, update->descriptorType, error)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to buffer descriptor with invalid buffer: " << buffer;
+                error_str << "Attempted write update to buffer descriptor failed due to: " << error->c_str();
                 *error = error_str.str();
                 return false;
             }
@@ -1041,13 +1243,13 @@
 }
 // Verify that the contents of the update are ok, but don't perform actual update
 bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescriptorSet *update, const DescriptorSet *src_set,
-                                                              const uint32_t index, std::string *error) const {
+                                                              VkDescriptorType type, uint32_t index, std::string *error) const {
     switch (src_set->descriptors_[index]->descriptor_class) {
     case PlainSampler: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             if (!src_set->descriptors_[index + di]->IsImmutableSampler()) {
                 auto update_sampler = static_cast<SamplerDescriptor *>(src_set->descriptors_[index + di].get())->GetSampler();
-                if (!ValidateSampler(update_sampler, sampler_map_)) {
+                if (!ValidateSampler(update_sampler, device_data_)) {
                     std::stringstream error_str;
                     error_str << "Attempted copy update to sampler descriptor with invalid sampler: " << update_sampler << ".";
                     *error = error_str.str();
@@ -1065,7 +1267,7 @@
             // First validate sampler
             if (!img_samp_desc->IsImmutableSampler()) {
                 auto update_sampler = img_samp_desc->GetSampler();
-                if (!ValidateSampler(update_sampler, sampler_map_)) {
+                if (!ValidateSampler(update_sampler, device_data_)) {
                     std::stringstream error_str;
                     error_str << "Attempted copy update to sampler descriptor with invalid sampler: " << update_sampler << ".";
                     *error = error_str.str();
@@ -1077,10 +1279,9 @@
             // Validate image
             auto image_view = img_samp_desc->GetImageView();
             auto image_layout = img_samp_desc->GetImageLayout();
-            if (!ValidateImageUpdate(image_view, image_layout, image_view_map_, image_map_, image_to_swapchain_map_, swapchain_map_,
-                                     error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to combined image sampler descriptor failed due to: " << error->c_str();
+                error_str << "Attempted copy update to combined image sampler descriptor failed due to: " << error->c_str();
                 *error = error_str.str();
                 return false;
             }
@@ -1091,10 +1292,9 @@
             auto img_desc = static_cast<const ImageDescriptor *>(src_set->descriptors_[index + di].get());
             auto image_view = img_desc->GetImageView();
             auto image_layout = img_desc->GetImageLayout();
-            if (!ValidateImageUpdate(image_view, image_layout, image_view_map_, image_map_, image_to_swapchain_map_, swapchain_map_,
-                                     error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to image descriptor failed due to: " << error->c_str();
+                error_str << "Attempted copy update to image descriptor failed due to: " << error->c_str();
                 *error = error_str.str();
                 return false;
             }
@@ -1104,9 +1304,17 @@
     case TexelBuffer: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto buffer_view = static_cast<TexelDescriptor *>(src_set->descriptors_[index + di].get())->GetBufferView();
-            if (!buffer_view_map_->count(buffer_view)) {
+            auto bv_info = getBufferViewInfo(device_data_, buffer_view);
+            if (!bv_info) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to texel buffer descriptor with invalid buffer view: " << buffer_view;
+                error_str << "Attempted copy update to texel buffer descriptor with invalid buffer view: " << buffer_view;
+                *error = error_str.str();
+                return false;
+            }
+            auto buffer = bv_info->buffer;
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error)) {
+                std::stringstream error_str;
+                error_str << "Attempted copy update to texel buffer descriptor failed due to: " << error->c_str();
                 *error = error_str.str();
                 return false;
             }
@@ -1116,9 +1324,9 @@
     case GeneralBuffer: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto buffer = static_cast<BufferDescriptor *>(src_set->descriptors_[index + di].get())->GetBuffer();
-            if (!buffer_map_->count(buffer)) {
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to buffer descriptor with invalid buffer: " << buffer;
+                error_str << "Attempted copy update to buffer descriptor failed due to: " << error->c_str();
                 *error = error_str.str();
                 return false;
             }
@@ -1131,4 +1339,76 @@
     }
     // All checks passed so update contents are good
     return true;
-}
\ No newline at end of file
+}
+// Verify that the state at allocate time is correct, but don't actually allocate the sets yet
+bool cvdescriptorset::ValidateAllocateDescriptorSets(const debug_report_data *report_data,
+                                                     const VkDescriptorSetAllocateInfo *p_alloc_info,
+                                                     const core_validation::layer_data *dev_data,
+                                                     AllocateDescriptorSetsData *ds_data) {
+    bool skip_call = false;
+
+    for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
+        auto layout = getDescriptorSetLayout(dev_data, p_alloc_info->pSetLayouts[i]);
+        if (!layout) {
+            skip_call |=
+                log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT,
+                        reinterpret_cast<const uint64_t &>(p_alloc_info->pSetLayouts[i]), __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS",
+                        "Unable to find set layout node for layout 0x%" PRIxLEAST64 " specified in vkAllocateDescriptorSets() call",
+                        reinterpret_cast<const uint64_t &>(p_alloc_info->pSetLayouts[i]));
+        } else {
+            ds_data->layout_nodes[i] = layout;
+            // Count total descriptors required per type
+            for (uint32_t j = 0; j < layout->GetBindingCount(); ++j) {
+                const auto &binding_layout = layout->GetDescriptorSetLayoutBindingPtrFromIndex(j);
+                uint32_t typeIndex = static_cast<uint32_t>(binding_layout->descriptorType);
+                ds_data->required_descriptors_by_type[typeIndex] += binding_layout->descriptorCount;
+            }
+        }
+    }
+    auto pool_node = getPoolNode(dev_data, p_alloc_info->descriptorPool);
+    // Track number of descriptorSets allowable in this pool
+    if (pool_node->availableSets < p_alloc_info->descriptorSetCount) {
+        skip_call |= log_msg(
+            report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
+            reinterpret_cast<uint64_t &>(pool_node->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS",
+            "Unable to allocate %u descriptorSets from pool 0x%" PRIxLEAST64 ". This pool only has %d descriptorSets remaining.",
+            p_alloc_info->descriptorSetCount, reinterpret_cast<uint64_t &>(pool_node->pool), pool_node->availableSets);
+    }
+    // Determine whether descriptor counts are satisfiable
+    for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
+        if (ds_data->required_descriptors_by_type[i] > pool_node->availableDescriptorTypeCount[i]) {
+            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
+                                 reinterpret_cast<const uint64_t &>(pool_node->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY,
+                                 "DS", "Unable to allocate %u descriptors of type %s from pool 0x%" PRIxLEAST64
+                                       ". This pool only has %d descriptors of this type remaining.",
+                                 ds_data->required_descriptors_by_type[i], string_VkDescriptorType(VkDescriptorType(i)),
+                                 reinterpret_cast<uint64_t &>(pool_node->pool), pool_node->availableDescriptorTypeCount[i]);
+        }
+    }
+
+    return skip_call;
+}
+// Decrement allocated sets from the pool and insert new sets into set_map
+void cvdescriptorset::PerformAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
+                                                    const VkDescriptorSet *descriptor_sets,
+                                                    const AllocateDescriptorSetsData *ds_data,
+                                                    std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> *pool_map,
+                                                    std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> *set_map,
+                                                    const core_validation::layer_data *dev_data) {
+    auto pool_state = (*pool_map)[p_alloc_info->descriptorPool];
+    /* Account for sets and individual descriptors allocated from pool */
+    pool_state->availableSets -= p_alloc_info->descriptorSetCount;
+    for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
+        pool_state->availableDescriptorTypeCount[i] -= ds_data->required_descriptors_by_type[i];
+    }
+    /* Create tracking object for each descriptor set; insert into
+     * global map and the pool's set.
+     */
+    for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
+        auto new_ds = new cvdescriptorset::DescriptorSet(descriptor_sets[i], ds_data->layout_nodes[i], dev_data);
+
+        pool_state->sets.insert(new_ds);
+        new_ds->in_use.store(0);
+        (*set_map)[descriptor_sets[i]] = new_ds;
+    }
+}
diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h
index 6f2073b..d8222a6 100644
--- a/layers/descriptor_sets.h
+++ b/layers/descriptor_sets.h
@@ -115,6 +115,7 @@
     VkSampler const *GetImmutableSamplerPtrFromBinding(const uint32_t) const;
     VkSampler const *GetImmutableSamplerPtrFromIndex(const uint32_t) const;
     // For a particular binding, get the global index
+    //  These calls should be guarded by a call to "HasBinding(binding)" to verify that the given binding exists
     uint32_t GetGlobalStartIndexFromBinding(const uint32_t) const;
     uint32_t GetGlobalEndIndexFromBinding(const uint32_t) const;
     // For a particular binding starting at offset and having update_count descriptors
@@ -160,10 +161,8 @@
 };
 // Shared helper functions - These are useful because the shared sampler image descriptor type
 //  performs common functions with both sampler and image descriptors so they can share their common functions
-bool ValidateSampler(const VkSampler, const std::unordered_map<VkSampler, std::unique_ptr<SAMPLER_NODE>> *);
-bool ValidateImageUpdate(const VkImageView, const VkImageLayout, const std::unordered_map<VkImageView, VkImageViewCreateInfo> *,
-                         const std::unordered_map<VkImage, IMAGE_NODE> *, const std::unordered_map<VkImage, VkSwapchainKHR> *,
-                         const std::unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> *, std::string *);
+bool ValidateSampler(const VkSampler, const core_validation::layer_data *);
+bool ValidateImageUpdate(VkImageView, VkImageLayout, VkDescriptorType, const core_validation::layer_data *, std::string *);
 
 class SamplerDescriptor : public Descriptor {
   public:
@@ -244,14 +243,28 @@
     VkDeviceSize offset_;
     VkDeviceSize range_;
 };
-// Helper functions for Updating descriptor sets since it crosses multiple sets
-// Validate will make sure an update is ok without actually performing it
-bool ValidateUpdateDescriptorSets(const debug_report_data *,
-                                  const std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> &, uint32_t,
+// Structs to contain common elements that need to be shared between Validate* and Perform* calls below
+struct AllocateDescriptorSetsData {
+    uint32_t required_descriptors_by_type[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
+    std::vector<cvdescriptorset::DescriptorSetLayout const *> layout_nodes;
+    AllocateDescriptorSetsData(uint32_t);
+};
+// Helper functions for descriptor set functions that cross multiple sets
+// "Validate" will make sure an update is ok without actually performing it
+bool ValidateUpdateDescriptorSets(const debug_report_data *, const core_validation::layer_data *, uint32_t,
                                   const VkWriteDescriptorSet *, uint32_t, const VkCopyDescriptorSet *);
-// Perform does the update with the assumption that ValidateUpdateDescriptorSets() has passed for the given update
-void PerformUpdateDescriptorSets(const std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> &, uint32_t,
-                                 const VkWriteDescriptorSet *, uint32_t, const VkCopyDescriptorSet *);
+// "Perform" does the update with the assumption that ValidateUpdateDescriptorSets() has passed for the given update
+void PerformUpdateDescriptorSets(const core_validation::layer_data *, uint32_t, const VkWriteDescriptorSet *, uint32_t,
+                                 const VkCopyDescriptorSet *);
+// Validate that Allocation state is ok
+bool ValidateAllocateDescriptorSets(const debug_report_data *, const VkDescriptorSetAllocateInfo *,
+                                    const core_validation::layer_data *, AllocateDescriptorSetsData *);
+// Update state based on allocating new descriptorsets
+void PerformAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *, const VkDescriptorSet *, const AllocateDescriptorSetsData *,
+                                   std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> *,
+                                   std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> *,
+                                   const core_validation::layer_data *);
+
 /*
  * DescriptorSet class
  *
@@ -273,13 +286,8 @@
 class DescriptorSet : public BASE_NODE {
   public:
     using BASE_NODE::in_use;
-    DescriptorSet(const VkDescriptorSet, const DescriptorSetLayout *, const std::unordered_map<VkBuffer, BUFFER_NODE> *,
-                  const std::unordered_map<VkDeviceMemory, DEVICE_MEM_INFO> *,
-                  const std::unordered_map<VkBufferView, VkBufferViewCreateInfo> *,
-                  const std::unordered_map<VkSampler, std::unique_ptr<SAMPLER_NODE>> *,
-                  const std::unordered_map<VkImageView, VkImageViewCreateInfo> *, const std::unordered_map<VkImage, IMAGE_NODE> *,
-                  const std::unordered_map<VkImage, VkSwapchainKHR> *,
-                  const std::unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> *);
+    using BASE_NODE::cb_bindings;
+    DescriptorSet(const VkDescriptorSet, const DescriptorSetLayout *, const core_validation::layer_data *);
     ~DescriptorSet();
     // A number of common Get* functions that return data based on layout from which this set was created
     uint32_t GetTotalDescriptorCount() const { return p_layout_ ? p_layout_->GetTotalDescriptorCount() : 0; };
@@ -305,14 +313,11 @@
     // Is this set compatible with the given layout?
     bool IsCompatible(const DescriptorSetLayout *, std::string *) const;
     // For given bindings validate state at time of draw is correct, returning false on error and writing error details into string*
-    bool ValidateDrawState(const std::unordered_set<uint32_t> &, const std::vector<uint32_t> &, std::string *) const;
+    bool ValidateDrawState(const std::unordered_map<uint32_t, descriptor_req> &, const std::vector<uint32_t> &, std::string *) const;
     // For given set of bindings, add any buffers and images that will be updated to their respective unordered_sets & return number
     // of objects inserted
-    uint32_t GetStorageUpdates(const std::unordered_set<uint32_t> &, std::unordered_set<VkBuffer> *,
+    uint32_t GetStorageUpdates(const std::unordered_map<uint32_t, descriptor_req> &, std::unordered_set<VkBuffer> *,
                                std::unordered_set<VkImageView> *) const;
-    // For all descriptors in a set, add any buffers and images that may be updated to their respective unordered_sets & return
-    // number of objects inserted
-    uint32_t GetAllStorageUpdates(std::unordered_set<VkBuffer> *, std::unordered_set<VkImageView> *) const;
 
     // Descriptor Update functions. These functions validate state and perform update separately
     // Validate contents of a WriteUpdate
@@ -327,11 +332,11 @@
     const DescriptorSetLayout *GetLayout() const { return p_layout_; };
     VkDescriptorSet GetSet() const { return set_; };
     // Return unordered_set of all command buffers that this set is bound to
-    std::unordered_set<GLOBAL_CB_NODE *> GetBoundCmdBuffers() const { return bound_cmd_buffers_; }
+    std::unordered_set<GLOBAL_CB_NODE *> GetBoundCmdBuffers() const { return cb_bindings; }
     // Bind given cmd_buffer to this descriptor set
-    void BindCommandBuffer(GLOBAL_CB_NODE *cb_node) { bound_cmd_buffers_.insert(cb_node); }
-    // If given cmd_buffer is in the bound_cmd_buffers_ set, remove it
-    void RemoveBoundCommandBuffer(GLOBAL_CB_NODE *cb_node) { bound_cmd_buffers_.erase(cb_node); }
+    void BindCommandBuffer(GLOBAL_CB_NODE *cb_node) { cb_bindings.insert(cb_node); }
+    // If given cmd_buffer is in the cb_bindings set, remove it
+    void RemoveBoundCommandBuffer(GLOBAL_CB_NODE *cb_node) { cb_bindings.erase(cb_node); }
     VkSampler const *GetImmutableSamplerPtrFromBinding(const uint32_t index) const {
         return p_layout_->GetImmutableSamplerPtrFromBinding(index);
     };
@@ -347,24 +352,18 @@
 
   private:
     bool VerifyWriteUpdateContents(const VkWriteDescriptorSet *, const uint32_t, std::string *) const;
-    bool VerifyCopyUpdateContents(const VkCopyDescriptorSet *, const DescriptorSet *, const uint32_t, std::string *) const;
+    bool VerifyCopyUpdateContents(const VkCopyDescriptorSet *, const DescriptorSet *, VkDescriptorType, uint32_t,
+                                  std::string *) const;
+    bool ValidateBufferUsage(BUFFER_NODE const *, VkDescriptorType, std::string *) const;
+    bool ValidateBufferUpdate(VkDescriptorBufferInfo const *, VkDescriptorType, std::string *) const;
     // Private helper to set all bound cmd buffers to INVALID state
     void InvalidateBoundCmdBuffers();
     bool some_update_; // has any part of the set ever been updated?
     VkDescriptorSet set_;
     const DescriptorSetLayout *p_layout_;
-    std::unordered_set<GLOBAL_CB_NODE *> bound_cmd_buffers_;
     std::vector<std::unique_ptr<Descriptor>> descriptors_;
-    // Ptrs to object containers to verify bound data
-    const std::unordered_map<VkBuffer, BUFFER_NODE> *buffer_map_;
-    const std::unordered_map<VkDeviceMemory, DEVICE_MEM_INFO> *memory_map_;
-    const std::unordered_map<VkBufferView, VkBufferViewCreateInfo> *buffer_view_map_;
-    const std::unordered_map<VkSampler, std::unique_ptr<SAMPLER_NODE>> *sampler_map_;
-    const std::unordered_map<VkImageView, VkImageViewCreateInfo> *image_view_map_;
-    // TODO : For next 3 maps all we really need (currently) is an image to format mapping
-    const std::unordered_map<VkImage, IMAGE_NODE> *image_map_;
-    const std::unordered_map<VkImage, VkSwapchainKHR> *image_to_swapchain_map_;
-    const std::unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> *swapchain_map_;
+    // Ptr to device data used for various data look-ups
+    const core_validation::layer_data *device_data_;
 };
 }
 #endif // CORE_VALIDATION_DESCRIPTOR_SETS_H_
diff --git a/layers/device_limits.cpp b/layers/device_limits.cpp
deleted file mode 100644
index a5b1ca7..0000000
--- a/layers/device_limits.cpp
+++ /dev/null
@@ -1,862 +0,0 @@
-/* Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 LunarG, Inc.
- * Copyright (C) 2015-2016 Google Inc.
- *
- * Licensed under the Apache 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
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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: Mark Lobodzinski <mark@lunarg.com>
- * Author: Mike Stroyan     <mike@LunarG.com>
- * Author: Tobin Ehlis      <tobin@lunarg.com>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unordered_map>
-#include <memory>
-
-#include "vk_loader_platform.h"
-#include "vk_dispatch_table_helper.h"
-#if defined(__GNUC__)
-#pragma GCC diagnostic ignored "-Wwrite-strings"
-#endif
-#if defined(__GNUC__)
-#pragma GCC diagnostic warning "-Wwrite-strings"
-#endif
-#include "vk_struct_size_helper.h"
-#include "device_limits.h"
-#include "vulkan/vk_layer.h"
-#include "vk_layer_config.h"
-#include "vk_enum_validate_helper.h"
-#include "vk_layer_table.h"
-#include "vk_layer_data.h"
-#include "vk_layer_logging.h"
-#include "vk_layer_extension_utils.h"
-#include "vk_layer_utils.h"
-
-namespace device_limits {
-
-// This struct will be stored in a map hashed by the dispatchable object
-struct layer_data {
-    VkInstance instance;
-
-    debug_report_data *report_data;
-    std::vector<VkDebugReportCallbackEXT> logging_callback;
-    VkLayerDispatchTable *device_dispatch_table;
-    VkLayerInstanceDispatchTable *instance_dispatch_table;
-    // Track state of each instance
-    unique_ptr<INSTANCE_STATE> instanceState;
-    unique_ptr<PHYSICAL_DEVICE_STATE> physicalDeviceState;
-    VkPhysicalDeviceFeatures actualPhysicalDeviceFeatures;
-    VkPhysicalDeviceFeatures requestedPhysicalDeviceFeatures;
-
-    // Track physical device per logical device
-    VkPhysicalDevice physicalDevice;
-    VkPhysicalDeviceProperties physicalDeviceProperties;
-    // Vector indices correspond to queueFamilyIndex
-    vector<unique_ptr<VkQueueFamilyProperties>> queueFamilyProperties;
-
-    layer_data()
-        : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), instanceState(nullptr),
-          physicalDeviceState(nullptr), actualPhysicalDeviceFeatures(), requestedPhysicalDeviceFeatures(), physicalDevice(){};
-};
-
-static unordered_map<void *, layer_data *> layer_data_map;
-
-// TODO : This can be much smarter, using separate locks for separate global data
-static int globalLockInitialized = 0;
-static loader_platform_thread_mutex globalLock;
-
-static void init_device_limits(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
-
-    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_device_limits");
-
-    if (!globalLockInitialized) {
-        // TODO/TBD: Need to delete this mutex sometime.  How???  One
-        // suggestion is to call this during vkCreateInstance(), and then we
-        // can clean it up during vkDestroyInstance().  However, that requires
-        // that the layer have per-instance locks.  We need to come back and
-        // address this soon.
-        loader_platform_thread_create_mutex(&globalLock);
-        globalLockInitialized = 1;
-    }
-}
-
-static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
-
-static const VkLayerProperties global_layer = {
-    "VK_LAYER_LUNARG_device_limits", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer",
-};
-
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
-    VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
-
-    assert(chain_info->u.pLayerInfo);
-    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
-    if (fpCreateInstance == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    // Advance the link info for the next element on the chain
-    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
-
-    VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
-    if (result != VK_SUCCESS)
-        return result;
-
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
-    my_data->instance = *pInstance;
-    my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
-    layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
-
-    my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance,
-                                                        pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
-
-    init_device_limits(my_data, pAllocator);
-    my_data->instanceState = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE());
-
-    return VK_SUCCESS;
-}
-
-/* hook DestroyInstance to remove tableInstanceMap entry */
-VKAPI_ATTR void VKAPI_CALL
-DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
-    dispatch_key key = get_dispatch_key(instance);
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
-    pTable->DestroyInstance(instance, pAllocator);
-
-    // Clean up logging callback, if any
-    while (my_data->logging_callback.size() > 0) {
-        VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
-        layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
-        my_data->logging_callback.pop_back();
-    }
-
-    layer_debug_report_destroy_instance(my_data->report_data);
-    delete my_data->instance_dispatch_table;
-    layer_data_map.erase(key);
-    if (layer_data_map.empty()) {
-        // Release mutex when destroying last instance.
-        loader_platform_thread_delete_mutex(&globalLock);
-        globalLockInitialized = 0;
-    }
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) {
-    bool skipCall = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    if (my_data->instanceState) {
-        // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS
-        if (NULL == pPhysicalDevices) {
-            my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_COUNT;
-        } else {
-            if (UNCALLED == my_data->instanceState->vkEnumeratePhysicalDevicesState) {
-                // Flag error here, shouldn't be calling this without having queried count
-                skipCall |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0,
-                            __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
-                            "Invalid call sequence to vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first "
-                            "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount.");
-            } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state
-            else if (my_data->instanceState->physicalDevicesCount != *pPhysicalDeviceCount) {
-                // TODO: Having actual count match count from app is not a requirement, so this can be a warning
-                skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
-                                    "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count "
-                                    "supported by this instance is %u.",
-                                    *pPhysicalDeviceCount, my_data->instanceState->physicalDevicesCount);
-            }
-            my_data->instanceState->vkEnumeratePhysicalDevicesState = QUERY_DETAILS;
-        }
-        if (skipCall)
-            return VK_ERROR_VALIDATION_FAILED_EXT;
-        VkResult result =
-            my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
-        if (NULL == pPhysicalDevices) {
-            my_data->instanceState->physicalDevicesCount = *pPhysicalDeviceCount;
-        } else { // Save physical devices
-            for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
-                layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map);
-                phy_dev_data->physicalDeviceState = unique_ptr<PHYSICAL_DEVICE_STATE>(new PHYSICAL_DEVICE_STATE());
-                // Init actual features for each physical device
-                my_data->instance_dispatch_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i],
-                                                                            &(phy_dev_data->actualPhysicalDeviceFeatures));
-            }
-        }
-        return result;
-    } else {
-        log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
-                DEVLIMITS_INVALID_INSTANCE, "DL", "Invalid instance (0x%" PRIxLEAST64 ") passed into vkEnumeratePhysicalDevices().",
-                (uint64_t)instance);
-    }
-    return VK_ERROR_VALIDATION_FAILED_EXT;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
-    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState = QUERY_DETAILS;
-    phy_dev_data->instance_dispatch_table->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
-    get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
-        ->instance_dispatch_table->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
-                                       VkImageUsageFlags usage, VkImageCreateFlags flags,
-                                       VkImageFormatProperties *pImageFormatProperties) {
-    return get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
-        ->instance_dispatch_table->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
-                                                                          pImageFormatProperties);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
-    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
-                                       VkQueueFamilyProperties *pQueueFamilyProperties) {
-    bool skipCall = false;
-    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    if (phy_dev_data->physicalDeviceState) {
-        if (NULL == pQueueFamilyProperties) {
-            phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
-        } else {
-            // Verify that for each physical device, this function is called first with NULL pQueueFamilyProperties ptr in order to
-            // get count
-            if (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
-                skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
-                                    "Invalid call sequence to vkGetPhysicalDeviceQueueFamilyProperties() w/ non-NULL "
-                                    "pQueueFamilyProperties. You should first call vkGetPhysicalDeviceQueueFamilyProperties() w/ "
-                                    "NULL pQueueFamilyProperties to query pCount.");
-            }
-            // Then verify that pCount that is passed in on second call matches what was returned
-            if (phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount != *pCount) {
-
-                // TODO: this is not a requirement of the Valid Usage section for vkGetPhysicalDeviceQueueFamilyProperties, so
-                // provide as warning
-                skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
-                                    "Call to vkGetPhysicalDeviceQueueFamilyProperties() w/ pCount value %u, but actual count "
-                                    "supported by this physicalDevice is %u.",
-                                    *pCount, phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount);
-            }
-            phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
-        }
-        if (skipCall)
-            return;
-        phy_dev_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount,
-                                                                                      pQueueFamilyProperties);
-        if (NULL == pQueueFamilyProperties) {
-            phy_dev_data->physicalDeviceState->queueFamilyPropertiesCount = *pCount;
-        } else { // Save queue family properties
-            phy_dev_data->queueFamilyProperties.reserve(*pCount);
-            for (uint32_t i = 0; i < *pCount; i++) {
-                phy_dev_data->queueFamilyProperties.emplace_back(new VkQueueFamilyProperties(pQueueFamilyProperties[i]));
-            }
-        }
-        return;
-    } else {
-        log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
-                __LINE__, DEVLIMITS_INVALID_PHYSICAL_DEVICE, "DL",
-                "Invalid physicalDevice (0x%" PRIxLEAST64 ") passed into vkGetPhysicalDeviceQueueFamilyProperties().",
-                (uint64_t)physicalDevice);
-    }
-}
-
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
-    get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
-        ->instance_dispatch_table->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
-                                             VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling,
-                                             uint32_t *pNumProperties, VkSparseImageFormatProperties *pProperties) {
-    get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map)
-        ->instance_dispatch_table->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage,
-                                                                                tiling, pNumProperties, pProperties);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) {
-    bool skipCall = false;
-    /* TODO: Verify viewportCount < maxViewports from VkPhysicalDeviceLimits */
-    if (!skipCall) {
-        layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-        my_data->device_dispatch_table->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
-    }
-}
-
-VKAPI_ATTR void VKAPI_CALL
-CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) {
-    bool skipCall = false;
-    /* TODO: Verify scissorCount < maxViewports from VkPhysicalDeviceLimits */
-    /* TODO: viewportCount and scissorCount must match at draw time */
-    if (!skipCall) {
-        layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-        my_data->device_dispatch_table->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
-    }
-}
-
-// Verify that features have been queried and verify that requested features are available
-static bool validate_features_request(layer_data *phy_dev_data) {
-    bool skipCall = false;
-    // Verify that all of the requested features are available
-    // Get ptrs into actual and requested structs and if requested is 1 but actual is 0, request is invalid
-    VkBool32 *actual = (VkBool32 *)&(phy_dev_data->actualPhysicalDeviceFeatures);
-    VkBool32 *requested = (VkBool32 *)&(phy_dev_data->requestedPhysicalDeviceFeatures);
-    // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues
-    //  Need to provide the struct member name with the issue. To do that seems like we'll
-    //  have to loop through each struct member which should be done w/ codegen to keep in synch.
-    uint32_t errors = 0;
-    uint32_t totalBools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
-    for (uint32_t i = 0; i < totalBools; i++) {
-        if (requested[i] > actual[i]) {
-            skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED,
-                                "DL", "While calling vkCreateDevice(), requesting feature #%u in VkPhysicalDeviceFeatures struct, "
-                                      "which is not available on this device.",
-                                i);
-            errors++;
-        }
-    }
-    if (errors && (UNCALLED == phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceFeaturesState)) {
-        // If user didn't request features, notify them that they should
-        // TODO: Verify this against the spec. I believe this is an invalid use of the API and should return an error
-        skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
-                            "You requested features that are unavailable on this device. You should first query feature "
-                            "availability by calling vkGetPhysicalDeviceFeatures().");
-    }
-    return skipCall;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
-             const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
-    bool skipCall = false;
-    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
-    // First check is app has actually requested queueFamilyProperties
-    if (!phy_dev_data->physicalDeviceState) {
-        skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
-                            "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices().");
-    } else if (QUERY_DETAILS != phy_dev_data->physicalDeviceState->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
-        // TODO: This is not called out as an invalid use in the spec so make more informative recommendation.
-        skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
-                            "DL", "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties().");
-    } else {
-        // Check that the requested queue properties are valid
-        for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
-            uint32_t requestedIndex = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
-            if (phy_dev_data->queueFamilyProperties.size() <=
-                requestedIndex) { // requested index is out of bounds for this physical device
-                skipCall |= log_msg(
-                    phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
-                    __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
-                    "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested.", requestedIndex);
-            } else if (pCreateInfo->pQueueCreateInfos[i].queueCount >
-                       phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount) {
-                skipCall |=
-                    log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
-                            "DL", "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but "
-                                  "requested queueCount is %u.",
-                            requestedIndex, phy_dev_data->queueFamilyProperties[requestedIndex]->queueCount,
-                            pCreateInfo->pQueueCreateInfos[i].queueCount);
-            }
-        }
-    }
-    // Check that any requested features are available
-    if (pCreateInfo->pEnabledFeatures) {
-        phy_dev_data->requestedPhysicalDeviceFeatures = *(pCreateInfo->pEnabledFeatures);
-        skipCall |= validate_features_request(phy_dev_data);
-    }
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-
-    VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
-
-    assert(chain_info->u.pLayerInfo);
-    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
-    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(phy_dev_data->instance, "vkCreateDevice");
-    if (fpCreateDevice == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    // Advance the link info for the next element on the chain
-    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
-
-    VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
-    if (result != VK_SUCCESS) {
-        return result;
-    }
-
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
-    my_device_data->device_dispatch_table = new VkLayerDispatchTable;
-    layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
-    my_device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice);
-    my_device_data->physicalDevice = gpu;
-
-    // Get physical device properties for this device
-    phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_device_data->physicalDeviceProperties));
-    return result;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
-    // Free device lifetime allocations
-    dispatch_key key = get_dispatch_key(device);
-    layer_data *my_device_data = get_my_data_ptr(key, layer_data_map);
-    my_device_data->device_dispatch_table->DestroyDevice(device, pAllocator);
-    delete my_device_data->device_dispatch_table;
-    layer_data_map.erase(key);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
-                 const VkAllocationCallbacks *pAllocator,
-                 VkRenderPass *pRenderPass) {
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skip_call = false;
-    uint32_t max_color_attachments = dev_data->physicalDeviceProperties.limits.maxColorAttachments;
-    for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
-        if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) {
-            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
-                                 reinterpret_cast<uint64_t>(device), __LINE__, DEVLIMITS_INVALID_ATTACHMENT_COUNT, "DL",
-                                 "Cannot create a render pass with %d color attachments. Max is %d.",
-                                 pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments);
-        }
-    }
-    if (skip_call) {
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    }
-    return dev_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
-                  const VkAllocationCallbacks *pAllocator,
-                  VkCommandPool *pCommandPool) {
-    // TODO : Verify that requested QueueFamilyIndex for this pool exists
-    VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-                          ->device_dispatch_table->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
-    return result;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
-    get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-        ->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
-    VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-                          ->device_dispatch_table->ResetCommandPool(device, commandPool, flags);
-    return result;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo, VkCommandBuffer *pCommandBuffer) {
-    VkResult result = get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-                          ->device_dispatch_table->AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer);
-    return result;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t count, const VkCommandBuffer *pCommandBuffers) {
-    get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-        ->device_dispatch_table->FreeCommandBuffers(device, commandPool, count, pCommandBuffers);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
-    bool skipCall = false;
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(dev_data->physicalDevice), layer_data_map);
-    const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
-    if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries == VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE) {
-        skipCall |= log_msg(
-            dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-            reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL",
-            "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support inheritedQueries.");
-    }
-    if (phy_dev_data->actualPhysicalDeviceFeatures.inheritedQueries != VK_FALSE && pInfo && pInfo->occlusionQueryEnable != VK_FALSE &&
-        !validate_VkQueryControlFlagBits(VkQueryControlFlagBits(pInfo->queryFlags))) {
-        skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVLIMITS_INVALID_INHERITED_QUERY, "DL",
-                            "Cannot enable in occlusion queries in vkBeginCommandBuffer() and set queryFlags to %d which is not a "
-                            "valid combination of VkQueryControlFlagBits.",
-                            pInfo->queryFlags);
-    }
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    if (!skipCall)
-        result = dev_data->device_dispatch_table->BeginCommandBuffer(commandBuffer, pBeginInfo);
-    return result;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
-    bool skipCall = false;
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkPhysicalDevice gpu = dev_data->physicalDevice;
-    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
-    if (queueFamilyIndex >=
-        phy_dev_data->queueFamilyProperties.size()) { // requested index is out of bounds for this physical device
-        skipCall |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
-                            "DL", "Invalid queueFamilyIndex %u requested in vkGetDeviceQueue().", queueFamilyIndex);
-    } else if (queueIndex >= phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount) {
-        skipCall |= log_msg(
-            phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
-            DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
-            "Invalid queue request in vkGetDeviceQueue(). QueueFamilyIndex %u only has %u queues, but requested queueIndex is %u.",
-            queueFamilyIndex, phy_dev_data->queueFamilyProperties[queueFamilyIndex]->queueCount, queueIndex);
-    }
-    if (!skipCall)
-        dev_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites,
-                       uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) {
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
-
-    for (uint32_t i = 0; i < descriptorWriteCount; i++) {
-        if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
-            (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
-            VkDeviceSize uniformAlignment = dev_data->physicalDeviceProperties.limits.minUniformBufferOffsetAlignment;
-            for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
-                if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) {
-                    skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                        VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
-                                        DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, "DL",
-                                        "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
-                                        ") must be a multiple of device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64,
-                                        i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment);
-                }
-            }
-        } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
-                   (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
-            VkDeviceSize storageAlignment = dev_data->physicalDeviceProperties.limits.minStorageBufferOffsetAlignment;
-            for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
-                if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) {
-                    skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                        VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
-                                        DEVLIMITS_INVALID_STORAGE_BUFFER_OFFSET, "DL",
-                                        "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
-                                        ") must be a multiple of device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64,
-                                        i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment);
-                }
-            }
-        }
-    }
-    if (!skipCall) {
-        dev_data->device_dispatch_table->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
-                                                              pDescriptorCopies);
-    }
-}
-
-VKAPI_ATTR void VKAPI_CALL
-CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
-                VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) {
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-
-    // dstOffset is the byte offset into the buffer to start updating and must be a multiple of 4.
-    if (dstOffset & 3) {
-        layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-        if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
-                    DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
-                    "vkCmdUpdateBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) {
-            return;
-        }
-    }
-
-    // dataSize is the number of bytes to update, which must be a multiple of 4.
-    if (dataSize & 3) {
-        layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-        if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
-                    DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
-                    "vkCmdUpdateBuffer parameter, VkDeviceSize dataSize, is not a multiple of 4")) {
-            return;
-        }
-    }
-
-    dev_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-
-    // dstOffset is the byte offset into the buffer to start filling and must be a multiple of 4.
-    if (dstOffset & 3) {
-        layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-        if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
-                    DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
-                    "vkCmdFillBuffer parameter, VkDeviceSize dstOffset, is not a multiple of 4")) {
-            return;
-        }
-    }
-
-    // size is the number of bytes to fill, which must be a multiple of 4.
-    if (size & 3) {
-        layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-        if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
-                    DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT, "DL",
-                    "vkCmdFillBuffer parameter, VkDeviceSize size, is not a multiple of 4")) {
-            return;
-        }
-    }
-
-    dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
-                             const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
-    if (VK_SUCCESS == res) {
-        res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
-    }
-    return res;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-DestroyDebugReportCallbackEXT(VkInstance instance,
-                              VkDebugReportCallbackEXT msgCallback,
-                              const VkAllocationCallbacks *pAllocator) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
-    layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
-                      size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
-                                                            pMsg);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
-                                   const char *pLayerName, uint32_t *pCount,
-                                   VkExtensionProperties *pProperties) {
-    if (pLayerName && !strcmp(pLayerName, global_layer.layerName))
-        return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
-
-    assert(physicalDevice);
-
-    dispatch_key key = get_dispatch_key(physicalDevice);
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount, pProperties);
-}
-
-static PFN_vkVoidFunction
-intercept_core_instance_command(const char *name);
-
-static PFN_vkVoidFunction
-intercept_core_device_command(const char *name);
-
-VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
-GetDeviceProcAddr(VkDevice dev, const char *funcName) {
-    PFN_vkVoidFunction proc = intercept_core_device_command(funcName);
-    if (proc)
-        return proc;
-
-    assert(dev);
-
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
-    VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
-    {
-        if (pTable->GetDeviceProcAddr == NULL)
-            return NULL;
-        return pTable->GetDeviceProcAddr(dev, funcName);
-    }
-}
-
-VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
-GetInstanceProcAddr(VkInstance instance, const char *funcName) {
-    PFN_vkVoidFunction proc = intercept_core_instance_command(funcName);
-    if (!proc)
-        intercept_core_device_command(funcName);
-    if (proc)
-        return proc;
-
-    layer_data *my_data;
-
-    assert(instance);
-    my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-
-    proc = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
-    if (proc)
-        return proc;
-
-    {
-        VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
-        if (pTable->GetInstanceProcAddr == NULL)
-            return NULL;
-        return pTable->GetInstanceProcAddr(instance, funcName);
-    }
-}
-
-static PFN_vkVoidFunction
-intercept_core_instance_command(const char *name) {
-    static const struct {
-        const char *name;
-        PFN_vkVoidFunction proc;
-    } core_instance_commands[] = {
-        { "vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr) },
-        { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) },
-        { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) },
-        { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) },
-        { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) },
-        { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) },
-        { "vkGetPhysicalDeviceFeatures", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFeatures) },
-        { "vkGetPhysicalDeviceFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFormatProperties) },
-        { "vkGetPhysicalDeviceImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceImageFormatProperties) },
-        { "vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties) },
-        { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) },
-        { "vkGetPhysicalDeviceMemoryProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMemoryProperties) },
-        { "vkGetPhysicalDeviceSparseImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSparseImageFormatProperties) },
-        { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) },
-    };
-
-    // we should never be queried for these commands
-    assert(strcmp(name, "vkEnumerateInstanceLayerProperties") &&
-           strcmp(name, "vkEnumerateInstanceExtensionProperties") &&
-           strcmp(name, "vkEnumerateDeviceLayerProperties"));
-
-    for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
-        if (!strcmp(core_instance_commands[i].name, name))
-            return core_instance_commands[i].proc;
-    }
-
-    return nullptr;
-}
-
-static PFN_vkVoidFunction
-intercept_core_device_command(const char *name) {
-    static const struct {
-        const char *name;
-        PFN_vkVoidFunction proc;
-    } core_device_commands[] = {
-        { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) },
-        { "vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice) },
-        { "vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue) },
-        { "vkCreateRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CreateRenderPass) },
-        { "vkCreateCommandPool", reinterpret_cast<PFN_vkVoidFunction>(CreateCommandPool) },
-        { "vkDestroyCommandPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyCommandPool) },
-        { "vkResetCommandPool", reinterpret_cast<PFN_vkVoidFunction>(ResetCommandPool) },
-        { "vkAllocateCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers) },
-        { "vkFreeCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(FreeCommandBuffers) },
-        { "vkBeginCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(BeginCommandBuffer) },
-        { "vkCmdUpdateBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdUpdateBuffer) },
-        { "vkUpdateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(UpdateDescriptorSets) },
-        { "vkCmdFillBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdFillBuffer) },
-        { "vkCmdSetScissor", reinterpret_cast<PFN_vkVoidFunction>(CmdSetScissor) },
-        { "vkCmdSetViewport", reinterpret_cast<PFN_vkVoidFunction>(CmdSetViewport) },
-    };
-
-    for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) {
-        if (!strcmp(core_device_commands[i].name, name))
-            return core_device_commands[i].proc;
-    }
-
-    return nullptr;
-}
-
-} // namespace device_limits
-
-// vk_layer_logging.h expects these to be defined
-
-VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
-                               const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
-    return device_limits::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-vkDestroyDebugReportCallbackEXT(VkInstance instance,
-                                VkDebugReportCallbackEXT msgCallback,
-                                const VkAllocationCallbacks *pAllocator) {
-    device_limits::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
-                        size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
-    device_limits::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
-}
-
-// loader-layer interface v0
-
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &device_limits::global_layer, pCount, pProperties);
-}
-
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &device_limits::global_layer, pCount, pProperties);
-}
-
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
-    return util_GetExtensionProperties(1, device_limits::instance_extensions, pCount, pProperties);
-}
-
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
-                                                                                    const char *pLayerName, uint32_t *pCount,
-                                                                                    VkExtensionProperties *pProperties) {
-    // the layer command handles VK_NULL_HANDLE just fine
-    return device_limits::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
-}
-
-VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
-    return device_limits::GetDeviceProcAddr(dev, funcName);
-}
-
-VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
-    if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties);
-    if (!strcmp(funcName, "vkGetInstanceProcAddr"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr);
-
-    return device_limits::GetInstanceProcAddr(instance, funcName);
-}
diff --git a/layers/device_limits.h b/layers/device_limits.h
deleted file mode 100644
index bec9dce..0000000
--- a/layers/device_limits.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 LunarG, Inc.
- *
- * Licensed under the Apache 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
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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: Tobin Ehlis <tobin@lunarg.com>
- * Author: Mark Lobodzinski <mark@lunarg.com>
- */
-
-#include "vulkan/vk_layer.h"
-#include <vector>
-
-using namespace std;
-
-// Device Limits ERROR codes
-enum DEV_LIMITS_ERROR {
-    DEVLIMITS_NONE,                          // Used for INFO & other non-error messages
-    DEVLIMITS_INVALID_INSTANCE,              // Invalid instance used
-    DEVLIMITS_INVALID_PHYSICAL_DEVICE,       // Invalid physical device used
-    DEVLIMITS_INVALID_INHERITED_QUERY,       // Invalid use of inherited query
-    DEVLIMITS_INVALID_ATTACHMENT_COUNT,      // Invalid value for the number of attachments
-    DEVLIMITS_MUST_QUERY_COUNT,              // Failed to make initial call to an API to query the count
-    DEVLIMITS_INVALID_CALL_SEQUENCE,         // Flag generic case of an invalid call sequence by the app
-    DEVLIMITS_INVALID_FEATURE_REQUESTED,     // App requested a feature not supported by physical device
-    DEVLIMITS_COUNT_MISMATCH,                // App requesting a count value different than actual value
-    DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,  // Invalid queue requested based on queue family properties
-    DEVLIMITS_INVALID_UNIFORM_BUFFER_OFFSET, // Uniform buffer offset violates device limit granularity
-    DEVLIMITS_INVALID_STORAGE_BUFFER_OFFSET, // Storage buffer offset violates device limit granularity
-    DEVLIMITS_INVALID_BUFFER_UPDATE_ALIGNMENT,  // Alignment requirement for buffer update is violated
-};
-
-enum CALL_STATE{
-    UNCALLED,      // Function has not been called
-    QUERY_COUNT,   // Function called once to query a count
-    QUERY_DETAILS, // Function called w/ a count to query details
-};
-
-struct INSTANCE_STATE {
-    // Track the call state and array size for physical devices
-    CALL_STATE vkEnumeratePhysicalDevicesState;
-    uint32_t physicalDevicesCount;
-    INSTANCE_STATE() : vkEnumeratePhysicalDevicesState(UNCALLED), physicalDevicesCount(0){};
-};
-
-struct PHYSICAL_DEVICE_STATE {
-    // Track the call state and array sizes for various query functions
-    CALL_STATE vkGetPhysicalDeviceQueueFamilyPropertiesState;
-    uint32_t queueFamilyPropertiesCount;
-    CALL_STATE vkGetPhysicalDeviceLayerPropertiesState;
-    uint32_t deviceLayerCount;
-    CALL_STATE vkGetPhysicalDeviceExtensionPropertiesState;
-    uint32_t deviceExtensionCount;
-    CALL_STATE vkGetPhysicalDeviceFeaturesState;
-    PHYSICAL_DEVICE_STATE()
-        : vkGetPhysicalDeviceQueueFamilyPropertiesState(UNCALLED), queueFamilyPropertiesCount(0),
-          vkGetPhysicalDeviceLayerPropertiesState(UNCALLED), deviceLayerCount(0),
-          vkGetPhysicalDeviceExtensionPropertiesState(UNCALLED), deviceExtensionCount(0),
-          vkGetPhysicalDeviceFeaturesState(UNCALLED){};
-};
diff --git a/layers/image.cpp b/layers/image.cpp
index 88ae5ba..8d789c6 100644
--- a/layers/image.cpp
+++ b/layers/image.cpp
@@ -90,7 +90,7 @@
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
     VkResult res = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
     if (res == VK_SUCCESS) {
-        res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
+        res = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
     }
     return res;
 }
@@ -399,49 +399,49 @@
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
-                                                const VkAllocationCallbacks *pAllocator,
-                                                VkRenderPass *pRenderPass) {
+                                                const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skipCall = false;
+    bool skip_call = false;
+    bool depth_format_present = false;
 
     for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
+        if (pCreateInfo->pAttachments[i].format == VK_FORMAT_UNDEFINED) {
+            std::stringstream ss;
+            ss << "vkCreateRenderPass: pCreateInfo->pAttachments[" << i << "].format is VK_FORMAT_UNDEFINED";
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
+        }
+
         if (!validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].initialLayout) ||
             !validate_VkImageLayoutKHR(pCreateInfo->pAttachments[i].finalLayout)) {
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkImageLayout in pCreateInfo->pAttachments[" << i << "], is unrecognized";
             // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
         }
-    }
 
-    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
         if (!validate_VkAttachmentLoadOp(pCreateInfo->pAttachments[i].loadOp)) {
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
             // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
         }
-    }
 
-    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
         if (!validate_VkAttachmentStoreOp(pCreateInfo->pAttachments[i].storeOp)) {
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp in pCreateInfo->pAttachments[" << i << "], is unrecognized";
             // TODO: Verify against Valid Use section of spec. Generally if something yield an undefined result, it's invalid
-            skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 IMAGE_RENDERPASS_INVALID_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
         }
+
+        // Any depth buffers specified as attachments?
+        depth_format_present |= vk_format_is_depth_or_stencil(pCreateInfo->pAttachments[i].format);
     }
 
-    // Any depth buffers specified as attachments?
-    bool depthFormatPresent = false;
-    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
-        depthFormatPresent |= vk_format_is_depth_or_stencil(pCreateInfo->pAttachments[i].format);
-    }
-
-    if (!depthFormatPresent) {
+    if (!depth_format_present) {
         // No depth attachment is present, validate that subpasses set depthStencilAttachment to VK_ATTACHMENT_UNUSED;
         for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
             if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment &&
@@ -449,13 +449,14 @@
                 std::stringstream ss;
                 ss << "vkCreateRenderPass has no depth/stencil attachment, yet subpass[" << i
                    << "] has VkSubpassDescription::depthStencilAttachment value that is not VK_ATTACHMENT_UNUSED";
-                skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                    IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
+                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                                     __LINE__, IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, "IMAGE", "%s", ss.str().c_str());
             }
         }
     }
-    if (skipCall)
+    if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
 
     VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
 
@@ -644,6 +645,12 @@
             skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
                                 reinterpret_cast<uint64_t &>(image), __LINE__, IMAGE_INVALID_FORMAT, "IMAGE", str);
         }
+
+        if (!(image_state->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) {
+            char const str[] = "vkCmdClearColorImage called with image created without VK_IMAGE_USAGE_TRANSFER_DST_BIT.";
+            skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                                reinterpret_cast<uint64_t &>(image), __LINE__, IMAGE_INVALID_USAGE, "IMAGE", str);
+        }
     }
 
     if (!skipCall) {
@@ -1286,6 +1293,24 @@
     phy_dev_data->instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, pProperties);
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, global_layer.layerName))
+        return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
+
+    return VK_ERROR_LAYER_NOT_PRESENT;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                   const char *pLayerName, uint32_t *pCount,
                                                                   VkExtensionProperties *pProperties) {
@@ -1353,15 +1378,13 @@
         { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) },
         { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) },
         { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) },
+        { "vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties) },
+        { "vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties) },
+        { "vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties) },
         { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) },
         { "vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties) },
     };
 
-    // we should never be queried for these commands
-    assert(strcmp(name, "vkEnumerateInstanceLayerProperties") &&
-           strcmp(name, "vkEnumerateInstanceExtensionProperties") &&
-           strcmp(name, "vkEnumerateDeviceLayerProperties"));
-
     for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
         if (!strcmp(core_instance_commands[i].name, name))
             return core_instance_commands[i].proc;
@@ -1425,27 +1448,30 @@
     image::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
 }
 
-// loader-layer interface v0
+// loader-layer interface v0, just wrappers since there is only a layer
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
-    return util_GetExtensionProperties(1, image::instance_extensions, pCount, pProperties);
+    return image::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &image::global_layer, pCount, pProperties);
+    return image::EnumerateInstanceLayerProperties(pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &image::global_layer, pCount, pProperties);
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return image::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                                     const char *pLayerName, uint32_t *pCount,
                                                                                     VkExtensionProperties *pProperties) {
-    // the layer command handles VK_NULL_HANDLE just fine
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
     return image::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
 }
 
@@ -1454,14 +1480,5 @@
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
-    if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties);
-    if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties);
-    if (!strcmp(funcName, "vkGetInstanceProcAddr"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr);
-
     return image::GetInstanceProcAddr(instance, funcName);
 }
diff --git a/layers/image.h b/layers/image.h
index 93b6c7e..6a6c76b 100644
--- a/layers/image.h
+++ b/layers/image.h
@@ -44,6 +44,7 @@
     IMAGE_INVALID_FORMAT_LIMITS_VIOLATION,  // Device limits for this format have been exceeded
     IMAGE_INVALID_LAYOUT,                   // Operation specifies an invalid layout
     IMAGE_INVALID_EXTENTS,                  // Operation specifies invalid image extents
+    IMAGE_INVALID_USAGE,                    // Image was created without necessary usage for operation
 };
 
 struct IMAGE_STATE {
@@ -54,13 +55,14 @@
     VkImageType imageType;
     VkExtent3D extent;
     VkImageCreateFlags flags;
+    VkImageUsageFlags usage;
     IMAGE_STATE()
         : mipLevels(0), arraySize(0), format(VK_FORMAT_UNDEFINED), samples(VK_SAMPLE_COUNT_1_BIT),
-          imageType(VK_IMAGE_TYPE_RANGE_SIZE), extent{}, flags(0){};
+          imageType(VK_IMAGE_TYPE_RANGE_SIZE), extent{}, flags(0), usage(0){};
     IMAGE_STATE(const VkImageCreateInfo *pCreateInfo)
         : mipLevels(pCreateInfo->mipLevels), arraySize(pCreateInfo->arrayLayers), format(pCreateInfo->format),
-          samples(pCreateInfo->samples), imageType(pCreateInfo->imageType), extent(pCreateInfo->extent),
-          flags(pCreateInfo->flags){};
+          samples(pCreateInfo->samples), imageType(pCreateInfo->imageType), extent(pCreateInfo->extent), flags(pCreateInfo->flags),
+          usage(pCreateInfo->usage){};
 };
 
 #endif // IMAGE_H
diff --git a/layers/linux/VkLayer_core_validation.json b/layers/linux/VkLayer_core_validation.json
index 1d8d305..3f2162d 100644
--- a/layers/linux/VkLayer_core_validation.json
+++ b/layers/linux/VkLayer_core_validation.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_core_validation",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_core_validation.so",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/linux/VkLayer_device_limits.json b/layers/linux/VkLayer_device_limits.json
deleted file mode 100644
index 6aab8a2..0000000
--- a/layers/linux/VkLayer_device_limits.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "file_format_version" : "1.0.0",
-    "layer" : {
-        "name": "VK_LAYER_LUNARG_device_limits",
-        "type": "GLOBAL",
-        "library_path": "./libVkLayer_device_limits.so",
-        "api_version": "1.0.13",
-        "implementation_version": "1",
-        "description": "LunarG Validation Layer",
-        "instance_extensions": [
-             {
-                 "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
-             }
-         ]
-    }
-}
diff --git a/layers/linux/VkLayer_image.json b/layers/linux/VkLayer_image.json
index 125e3fc..97a250e 100644
--- a/layers/linux/VkLayer_image.json
+++ b/layers/linux/VkLayer_image.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_image",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_image.so",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/linux/VkLayer_object_tracker.json b/layers/linux/VkLayer_object_tracker.json
index e778c64..1c5d79b 100644
--- a/layers/linux/VkLayer_object_tracker.json
+++ b/layers/linux/VkLayer_object_tracker.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_object_tracker",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_object_tracker.so",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/linux/VkLayer_parameter_validation.json b/layers/linux/VkLayer_parameter_validation.json
index ba1f151..899ea88 100644
--- a/layers/linux/VkLayer_parameter_validation.json
+++ b/layers/linux/VkLayer_parameter_validation.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_parameter_validation",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_parameter_validation.so",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/linux/VkLayer_swapchain.json b/layers/linux/VkLayer_swapchain.json
index 059c028..5fe0ef8 100644
--- a/layers/linux/VkLayer_swapchain.json
+++ b/layers/linux/VkLayer_swapchain.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_swapchain",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_swapchain.so",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/linux/VkLayer_threading.json b/layers/linux/VkLayer_threading.json
index 6b7ba32..59feb59 100644
--- a/layers/linux/VkLayer_threading.json
+++ b/layers/linux/VkLayer_threading.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_GOOGLE_threading",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_threading.so",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "Google Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/linux/VkLayer_unique_objects.json b/layers/linux/VkLayer_unique_objects.json
index 8901ebd..59e1f89 100644
--- a/layers/linux/VkLayer_unique_objects.json
+++ b/layers/linux/VkLayer_unique_objects.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_unique_objects",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_unique_objects.so",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "Google Validation Layer"
     }
diff --git a/layers/object_tracker.cpp b/layers/object_tracker.cpp
new file mode 100644
index 0000000..e3d49b5
--- /dev/null
+++ b/layers/object_tracker.cpp
@@ -0,0 +1,4004 @@
+/*
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ * Copyright (c) 2015-2016 Google, Inc.
+ *
+ * Licensed under the Apache 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Tobin Ehlis <tobine@google.com>
+ * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Mike Stroyan <stroyan@google.com>
+ * Author: Tony Barbour <tony@LunarG.com>
+ */
+
+#include "vk_loader_platform.h"
+#include "vulkan/vulkan.h"
+
+#include <cinttypes>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unordered_map>
+
+#include "vk_layer_config.h"
+#include "vk_layer_data.h"
+#include "vk_layer_logging.h"
+#include "vk_layer_table.h"
+#include "vulkan/vk_layer.h"
+
+#include "object_tracker.h"
+
+namespace object_tracker {
+
+static void InitObjectTracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
+
+    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_object_tracker");
+}
+
+// Add new queue to head of global queue list
+static void AddQueueInfo(VkDevice device, uint32_t queue_node_index, VkQueue queue) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    auto queueItem = device_data->queue_info_map.find(queue);
+    if (queueItem == device_data->queue_info_map.end()) {
+        OT_QUEUE_INFO *p_queue_info = new OT_QUEUE_INFO;
+        if (p_queue_info != NULL) {
+            memset(p_queue_info, 0, sizeof(OT_QUEUE_INFO));
+            p_queue_info->queue = queue;
+            p_queue_info->queue_node_index = queue_node_index;
+            device_data->queue_info_map[queue] = p_queue_info;
+        } else {
+            log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
+                    reinterpret_cast<uint64_t>(queue), __LINE__, OBJTRACK_INTERNAL_ERROR, LayerName,
+                    "ERROR:  VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
+        }
+    }
+}
+
+// Destroy memRef lists and free all memory
+static void DestroyQueueDataStructures(VkDevice device) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
+    for (auto queue_item : device_data->queue_info_map) {
+        delete queue_item.second;
+    }
+    device_data->queue_info_map.clear();
+
+    // Destroy the items in the queue map
+    auto queue = device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT].begin();
+    while (queue != device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT].end()) {
+        uint32_t obj_index = queue->second->object_type;
+        assert(device_data->num_total_objects > 0);
+        device_data->num_total_objects--;
+        assert(device_data->num_objects[obj_index] > 0);
+        device_data->num_objects[obj_index]--;
+        log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, queue->second->object_type, queue->second->handle,
+                __LINE__, OBJTRACK_NONE, LayerName,
+                "OBJ_STAT Destroy Queue obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " Queue objs).",
+                queue->second->handle, device_data->num_total_objects, device_data->num_objects[obj_index]);
+        delete queue->second;
+        queue = device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT].erase(queue);
+    }
+}
+
+// Check Queue type flags for selected queue operations
+static void ValidateQueueFlags(VkQueue queue, const char *function) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
+    auto queue_item = device_data->queue_info_map.find(queue);
+    if (queue_item != device_data->queue_info_map.end()) {
+        OT_QUEUE_INFO *pQueueInfo = queue_item->second;
+        if (pQueueInfo != NULL) {
+            layer_data *instance_data = get_my_data_ptr(get_dispatch_key(device_data->physical_device), layer_data_map);
+            if ((instance_data->queue_family_properties[pQueueInfo->queue_node_index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) ==
+                0) {
+                log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
+                        reinterpret_cast<uint64_t>(queue), __LINE__, OBJTRACK_UNKNOWN_OBJECT, LayerName,
+                        "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
+            }
+        }
+    }
+}
+
+static void AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, const VkCommandBuffer command_buffer,
+                                  VkDebugReportObjectTypeEXT object_type, VkCommandBufferLevel level) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
+    log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, object_type, reinterpret_cast<const uint64_t>(command_buffer),
+            __LINE__, OBJTRACK_NONE, LayerName, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
+            string_VkDebugReportObjectTypeEXT(object_type), reinterpret_cast<const uint64_t>(command_buffer));
+
+    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
+    pNewObjNode->object_type = object_type;
+    pNewObjNode->handle = reinterpret_cast<const uint64_t>(command_buffer);
+    pNewObjNode->parent_object = reinterpret_cast<const uint64_t &>(command_pool);
+    if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
+        pNewObjNode->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
+    } else {
+        pNewObjNode->status = OBJSTATUS_NONE;
+    }
+    device_data->object_map[object_type][reinterpret_cast<const uint64_t>(command_buffer)] = pNewObjNode;
+    device_data->num_objects[object_type]++;
+    device_data->num_total_objects++;
+}
+
+static bool ValidateCommandBuffer(VkDevice device, VkCommandPool command_pool, VkCommandBuffer command_buffer) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    bool skip_call = false;
+    uint64_t object_handle = reinterpret_cast<uint64_t>(command_buffer);
+    if (device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT].find(object_handle) !=
+        device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT].end()) {
+        OBJTRACK_NODE *pNode =
+            device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT][reinterpret_cast<uint64_t>(command_buffer)];
+
+        if (pNode->parent_object != reinterpret_cast<uint64_t &>(command_pool)) {
+            skip_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->object_type, object_handle,
+                                 __LINE__, OBJTRACK_COMMAND_POOL_MISMATCH, LayerName,
+                                 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64
+                                 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
+                                 reinterpret_cast<uint64_t>(command_buffer), pNode->parent_object,
+                                 reinterpret_cast<uint64_t &>(command_pool));
+        }
+    } else {
+        skip_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle,
+                             __LINE__, OBJTRACK_NONE, LayerName, "Unable to remove command buffer obj 0x%" PRIxLEAST64
+                                                                 ". Was it created? Has it already been destroyed?",
+                             object_handle);
+    }
+    return skip_call;
+}
+
+static void AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set,
+                                  VkDebugReportObjectTypeEXT object_type) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
+    log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, object_type,
+            reinterpret_cast<uint64_t &>(descriptor_set), __LINE__, OBJTRACK_NONE, LayerName,
+            "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++, object_name[object_type],
+            reinterpret_cast<uint64_t &>(descriptor_set));
+
+    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
+    pNewObjNode->object_type = object_type;
+    pNewObjNode->status = OBJSTATUS_NONE;
+    pNewObjNode->handle = reinterpret_cast<uint64_t &>(descriptor_set);
+    pNewObjNode->parent_object = reinterpret_cast<uint64_t &>(descriptor_pool);
+    device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT][reinterpret_cast<uint64_t &>(descriptor_set)] =
+        pNewObjNode;
+    device_data->num_objects[object_type]++;
+    device_data->num_total_objects++;
+}
+
+static bool ValidateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    bool skip_call = false;
+    uint64_t object_handle = reinterpret_cast<uint64_t &>(descriptor_set);
+    auto dsItem = device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT].find(object_handle);
+    if (dsItem != device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT].end()) {
+        OBJTRACK_NODE *pNode = dsItem->second;
+
+        if (pNode->parent_object != reinterpret_cast<uint64_t &>(descriptor_pool)) {
+            skip_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->object_type, object_handle,
+                                 __LINE__, OBJTRACK_DESCRIPTOR_POOL_MISMATCH, LayerName,
+                                 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64
+                                 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
+                                 reinterpret_cast<uint64_t &>(descriptor_set), pNode->parent_object,
+                                 reinterpret_cast<uint64_t &>(descriptor_pool));
+        }
+    } else {
+        skip_call |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle,
+                             __LINE__, OBJTRACK_NONE, LayerName, "Unable to remove descriptor set obj 0x%" PRIxLEAST64
+                                                                 ". Was it created? Has it already been destroyed?",
+                             object_handle);
+    }
+    return skip_call;
+}
+
+static void CreateQueue(VkDevice device, VkQueue vkObj, VkDebugReportObjectTypeEXT object_type) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
+    log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, object_type, reinterpret_cast<uint64_t>(vkObj), __LINE__,
+            OBJTRACK_NONE, LayerName, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
+            object_name[object_type], reinterpret_cast<uint64_t>(vkObj));
+
+    OBJTRACK_NODE *p_obj_node = NULL;
+    auto queue_item = device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT].find(reinterpret_cast<uint64_t>(vkObj));
+    if (queue_item == device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT].end()) {
+        p_obj_node = new OBJTRACK_NODE;
+        device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT][reinterpret_cast<uint64_t>(vkObj)] = p_obj_node;
+        device_data->num_objects[object_type]++;
+        device_data->num_total_objects++;
+    } else {
+        p_obj_node = queue_item->second;
+    }
+    p_obj_node->object_type = object_type;
+    p_obj_node->status = OBJSTATUS_NONE;
+    p_obj_node->handle = reinterpret_cast<uint64_t>(vkObj);
+}
+
+static void CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
+    log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+            reinterpret_cast<uint64_t &>(swapchain_image), __LINE__, OBJTRACK_NONE, LayerName,
+            "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++, "SwapchainImage",
+            reinterpret_cast<uint64_t &>(swapchain_image));
+
+    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
+    pNewObjNode->object_type = VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT;
+    pNewObjNode->status = OBJSTATUS_NONE;
+    pNewObjNode->handle = reinterpret_cast<uint64_t &>(swapchain_image);
+    pNewObjNode->parent_object = reinterpret_cast<uint64_t &>(swapchain);
+    device_data->swapchainImageMap[reinterpret_cast<uint64_t &>(swapchain_image)] = pNewObjNode;
+}
+
+template <typename T1, typename T2>
+static void CreateDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type) {
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
+
+    log_msg(instance_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, object_type, reinterpret_cast<uint64_t>(object),
+            __LINE__, OBJTRACK_NONE, LayerName, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
+            object_name[object_type], reinterpret_cast<uint64_t>(object));
+
+    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
+    pNewObjNode->object_type = object_type;
+    pNewObjNode->status = OBJSTATUS_NONE;
+    pNewObjNode->handle = reinterpret_cast<uint64_t>(object);
+    instance_data->object_map[object_type][reinterpret_cast<uint64_t>(object)] = pNewObjNode;
+    instance_data->num_objects[object_type]++;
+    instance_data->num_total_objects++;
+}
+
+template <typename T1, typename T2>
+static void CreateNonDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
+
+    log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, object_type, reinterpret_cast<uint64_t &>(object),
+            __LINE__, OBJTRACK_NONE, LayerName, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
+            object_name[object_type], reinterpret_cast<uint64_t &>(object));
+
+    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
+    pNewObjNode->object_type = object_type;
+    pNewObjNode->status = OBJSTATUS_NONE;
+    pNewObjNode->handle = reinterpret_cast<uint64_t &>(object);
+    device_data->object_map[object_type][reinterpret_cast<uint64_t &>(object)] = pNewObjNode;
+    device_data->num_objects[object_type]++;
+    device_data->num_total_objects++;
+}
+
+template <typename T1, typename T2>
+static void DestroyDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type) {
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
+
+    uint64_t object_handle = reinterpret_cast<uint64_t>(object);
+
+    auto item = instance_data->object_map[object_type].find(object_handle);
+    if (item != instance_data->object_map[object_type].end()) {
+
+        OBJTRACK_NODE *pNode = item->second;
+        assert(instance_data->num_total_objects > 0);
+        instance_data->num_total_objects--;
+        assert(instance_data->num_objects[object_type] > 0);
+        instance_data->num_objects[pNode->object_type]--;
+
+        log_msg(instance_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->object_type, object_handle, __LINE__,
+                OBJTRACK_NONE, LayerName,
+                "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
+                object_name[pNode->object_type], reinterpret_cast<uint64_t>(object), instance_data->num_total_objects,
+                instance_data->num_objects[pNode->object_type], object_name[pNode->object_type]);
+
+        delete pNode;
+        instance_data->object_map[object_type].erase(item);
+    } else {
+        log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__,
+                OBJTRACK_UNKNOWN_OBJECT, LayerName,
+                "Unable to remove %s obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
+                object_name[object_type], object_handle);
+    }
+}
+
+template <typename T1, typename T2>
+static void DestroyNonDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
+
+    uint64_t object_handle = reinterpret_cast<uint64_t &>(object);
+
+    auto item = device_data->object_map[object_type].find(object_handle);
+    if (item != device_data->object_map[object_type].end()) {
+
+        OBJTRACK_NODE *pNode = item->second;
+        assert(device_data->num_total_objects > 0);
+        device_data->num_total_objects--;
+        assert(device_data->num_objects[pNode->object_type] > 0);
+        device_data->num_objects[pNode->object_type]--;
+
+        log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->object_type, object_handle, __LINE__,
+                OBJTRACK_NONE, LayerName,
+                "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
+                object_name[pNode->object_type], reinterpret_cast<uint64_t &>(object), device_data->num_total_objects,
+                device_data->num_objects[pNode->object_type], object_name[pNode->object_type]);
+
+        delete pNode;
+        device_data->object_map[object_type].erase(item);
+    } else {
+        log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__,
+                OBJTRACK_UNKNOWN_OBJECT, LayerName,
+                "Unable to remove %s obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
+                object_name[object_type], object_handle);
+    }
+}
+
+template <typename T1, typename T2>
+static bool ValidateDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type,
+                                       bool null_allowed) {
+    if (null_allowed && (object == VK_NULL_HANDLE)) {
+        return false;
+    }
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
+
+    if (instance_data->object_map[object_type].find(reinterpret_cast<uint64_t>(object)) ==
+        instance_data->object_map[object_type].end()) {
+        return log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, reinterpret_cast<uint64_t>(object),
+                       __LINE__, OBJTRACK_INVALID_OBJECT, LayerName, "Invalid %s Object 0x%" PRIxLEAST64, object_name[object_type],
+                       reinterpret_cast<uint64_t>(object));
+    }
+    return false;
+}
+
+template <typename T1, typename T2>
+static bool ValidateNonDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type,
+                                          bool null_allowed) {
+    if (null_allowed && (object == VK_NULL_HANDLE)) {
+        return false;
+    }
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
+    if (device_data->object_map[object_type].find(reinterpret_cast<uint64_t &>(object)) ==
+        device_data->object_map[object_type].end()) {
+        // If object is an image, also look for it in the swapchain image map
+        if ((object_type != VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT) ||
+            (device_data->swapchainImageMap.find(reinterpret_cast<uint64_t &>(object)) == device_data->swapchainImageMap.end())) {
+            return log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type,
+                           reinterpret_cast<uint64_t &>(object), __LINE__, OBJTRACK_INVALID_OBJECT, LayerName,
+                           "Invalid %s Object 0x%" PRIxLEAST64, object_name[object_type], reinterpret_cast<uint64_t &>(object));
+        }
+    }
+    return false;
+}
+
+static void DeviceReportUndestroyedObjects(VkDevice device, VkDebugReportObjectTypeEXT object_type) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    for (auto item = device_data->object_map[object_type].begin(); item != device_data->object_map[object_type].end();) {
+        OBJTRACK_NODE *object_info = item->second;
+        log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_info->object_type, object_info->handle, __LINE__,
+                OBJTRACK_OBJECT_LEAK, LayerName,
+                "OBJ ERROR : For device 0x%" PRIxLEAST64 ", %s object 0x%" PRIxLEAST64 " has not been destroyed.",
+                reinterpret_cast<uint64_t>(device), object_name[object_type], object_info->handle);
+        item = device_data->object_map[object_type].erase(item);
+    }
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
+    std::unique_lock<std::mutex> lock(global_lock);
+
+    dispatch_key key = get_dispatch_key(instance);
+    layer_data *instance_data = get_my_data_ptr(key, layer_data_map);
+
+    // Enable the temporary callback(s) here to catch cleanup issues:
+    bool callback_setup = false;
+    if (instance_data->num_tmp_callbacks > 0) {
+        if (!layer_enable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks,
+                                        instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks)) {
+            callback_setup = true;
+        }
+    }
+
+    ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+
+    DestroyDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
+    // Report any remaining objects in LL
+
+    for (auto iit = instance_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT].begin();
+         iit != instance_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT].end();) {
+        OBJTRACK_NODE *pNode = iit->second;
+
+        VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
+
+        log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->object_type, pNode->handle, __LINE__,
+                OBJTRACK_OBJECT_LEAK, LayerName, "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.",
+                string_VkDebugReportObjectTypeEXT(pNode->object_type), pNode->handle);
+        // Semaphore:
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT);
+        DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+        // DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT);
+    }
+    instance_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT].clear();
+
+    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
+    pInstanceTable->DestroyInstance(instance, pAllocator);
+
+    // Disable and cleanup the temporary callback(s):
+    if (callback_setup) {
+        layer_disable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks, instance_data->tmp_callbacks);
+    }
+    if (instance_data->num_tmp_callbacks > 0) {
+        layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
+        instance_data->num_tmp_callbacks = 0;
+    }
+
+    // Clean up logging callback, if any
+    while (instance_data->logging_callback.size() > 0) {
+        VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
+        layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
+        instance_data->logging_callback.pop_back();
+    }
+
+    layer_debug_report_destroy_instance(instance_data->report_data);
+    layer_data_map.erase(key);
+
+    instanceExtMap.erase(pInstanceTable);
+    lock.unlock();
+    ot_instance_table_map.erase(key);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
+
+    std::unique_lock<std::mutex> lock(global_lock);
+    ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    DestroyDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
+
+    // Report any remaining objects associated with this VkDevice object in LL
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT);
+    // DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT);
+    // DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+    DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+    // DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT);
+
+    // Clean up Queue's MemRef Linked Lists
+    DestroyQueueDataStructures(device);
+
+    lock.unlock();
+
+    dispatch_key key = get_dispatch_key(device);
+    VkLayerDispatchTable *pDisp = get_dispatch_table(ot_device_table_map, device);
+    pDisp->DestroyDevice(device, pAllocator);
+    ot_device_table_map.erase(key);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_instance_table_map, physicalDevice)->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+                                                             VkFormatProperties *pFormatProperties) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_instance_table_map, physicalDevice)
+        ->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+                                                                      VkImageType type, VkImageTiling tiling,
+                                                                      VkImageUsageFlags usage, VkImageCreateFlags flags,
+                                                                      VkImageFormatProperties *pImageFormatProperties) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_instance_table_map, physicalDevice)
+            ->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, pImageFormatProperties);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_instance_table_map, physicalDevice)->GetPhysicalDeviceProperties(physicalDevice, pProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
+                                                             VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_instance_table_map, physicalDevice)->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
+}
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *pName);
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *pName);
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount,
+                                                                    VkExtensionProperties *pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pPropertyCount, VkLayerProperties *pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
+                                                              VkLayerProperties *pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(queue, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, true);
+        if (pSubmits) {
+            for (uint32_t idx0 = 0; idx0 < submitCount; ++idx0) {
+                if (pSubmits[idx0].pCommandBuffers) {
+                    for (uint32_t idx1 = 0; idx1 < pSubmits[idx0].commandBufferCount; ++idx1) {
+                        skip_call |= ValidateDispatchableObject(queue, pSubmits[idx0].pCommandBuffers[idx1],
+                                                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+                    }
+                }
+                if (pSubmits[idx0].pSignalSemaphores) {
+                    for (uint32_t idx2 = 0; idx2 < pSubmits[idx0].signalSemaphoreCount; ++idx2) {
+                        skip_call |= ValidateNonDispatchableObject(queue, pSubmits[idx0].pSignalSemaphores[idx2],
+                                                                   VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false);
+                    }
+                }
+                if (pSubmits[idx0].pWaitSemaphores) {
+                    for (uint32_t idx3 = 0; idx3 < pSubmits[idx0].waitSemaphoreCount; ++idx3) {
+                        skip_call |= ValidateNonDispatchableObject(queue, pSubmits[idx0].pWaitSemaphores[idx3],
+                                                                   VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false);
+                    }
+                }
+            }
+        }
+        if (queue) {
+            skip_call |= ValidateDispatchableObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false);
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, queue)->QueueSubmit(queue, submitCount, pSubmits, fence);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL QueueWaitIdle(VkQueue queue) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, queue)->QueueWaitIdle(queue);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL DeviceWaitIdle(VkDevice device) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->DeviceWaitIdle(device);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
+                                              const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pMemory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL FlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
+                                                       const VkMappedMemoryRange *pMemoryRanges) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pMemoryRanges) {
+            for (uint32_t idx0 = 0; idx0 < memoryRangeCount; ++idx0) {
+                if (pMemoryRanges[idx0].memory) {
+                    skip_call |= ValidateNonDispatchableObject(device, pMemoryRanges[idx0].memory,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+                }
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL InvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
+                                                            const VkMappedMemoryRange *pMemoryRanges) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pMemoryRanges) {
+            for (uint32_t idx0 = 0; idx0 < memoryRangeCount; ++idx0) {
+                if (pMemoryRanges[idx0].memory) {
+                    skip_call |= ValidateNonDispatchableObject(device, pMemoryRanges[idx0].memory,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+                }
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->InvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory,
+                                                     VkDeviceSize *pCommittedMemoryInBytes) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, device)->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory,
+                                                VkDeviceSize memoryOffset) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->BindBufferMemory(device, buffer, memory, memoryOffset);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->BindImageMemory(device, image, memory, memoryOffset);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
+                                                       VkMemoryRequirements *pMemoryRequirements) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, device)->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, device)->GetImageMemoryRequirements(device, image, pMemoryRequirements);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
+                                                            VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, device)
+        ->GetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+                                                                        VkImageType type, VkSampleCountFlagBits samples,
+                                                                        VkImageUsageFlags usage, VkImageTiling tiling,
+                                                                        uint32_t *pPropertyCount,
+                                                                        VkSparseImageFormatProperties *pProperties) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_instance_table_map, physicalDevice)
+        ->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, pPropertyCount,
+                                                       pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
+                                           const VkAllocationCallbacks *pAllocator, VkFence *pFence) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateFence(device, pCreateInfo, pAllocator, pFence);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pFence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyFence(device, fence, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL ResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pFences) {
+            for (uint32_t idx0 = 0; idx0 < fenceCount; ++idx0) {
+                skip_call |= ValidateNonDispatchableObject(device, pFences[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false);
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->ResetFences(device, fenceCount, pFences);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetFenceStatus(VkDevice device, VkFence fence) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->GetFenceStatus(device, fence);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll,
+                                             uint64_t timeout) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pFences) {
+            for (uint32_t idx0 = 0; idx0 < fenceCount; ++idx0) {
+                skip_call |= ValidateNonDispatchableObject(device, pFences[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false);
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
+                                               const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pSemaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroySemaphore(device, semaphore, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
+                                           const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateEvent(device, pCreateInfo, pAllocator, pEvent);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pEvent, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyEvent(device, event, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetEventStatus(VkDevice device, VkEvent event) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->GetEventStatus(device, event);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL SetEvent(VkDevice device, VkEvent event) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->SetEvent(device, event);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL ResetEvent(VkDevice device, VkEvent event) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->ResetEvent(device, event);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
+                                               const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pQueryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyQueryPool(device, queryPool, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
+                                                   size_t dataSize, void *pData, VkDeviceSize stride, VkQueryResultFlags flags) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)
+                          ->GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
+                                            const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyBuffer(device, buffer, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
+                                                const VkAllocationCallbacks *pAllocator, VkBufferView *pView) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pCreateInfo) {
+            skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateBufferView(device, pCreateInfo, pAllocator, pView);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(device, bufferView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, false);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, bufferView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyBufferView(device, bufferView, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
+                                           const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateImage(device, pCreateInfo, pAllocator, pImage);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyImage(device, image, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource,
+                                                     VkSubresourceLayout *pLayout) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, device)->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
+                                               const VkAllocationCallbacks *pAllocator, VkImageView *pView) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pCreateInfo) {
+            skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateImageView(device, pCreateInfo, pAllocator, pView);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, imageView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, imageView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyImageView(device, imageView, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
+                                                  const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pShaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
+                                               const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, shaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, shaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyShaderModule(device, shaderModule, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkPipelineCache *pPipelineCache) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pPipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache,
+                                                const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyPipelineCache(device, pipelineCache, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize,
+                                                    void *pData) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount,
+                                                   const VkPipelineCache *pSrcCaches) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, dstCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+        if (pSrcCaches) {
+            for (uint32_t idx0 = 0; idx0 < srcCacheCount; ++idx0) {
+                skip_call |=
+                    ValidateNonDispatchableObject(device, pSrcCaches[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyPipeline(device, pipeline, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
+                                                    const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pCreateInfo) {
+            if (pCreateInfo->pSetLayouts) {
+                for (uint32_t idx0 = 0; idx0 < pCreateInfo->setLayoutCount; ++idx0) {
+                    skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->pSetLayouts[idx0],
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
+                }
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pPipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
+                                                 const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, pipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, pipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
+                                             const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->CreateSampler(device, pCreateInfo, pAllocator, pSampler);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pSampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, sampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, sampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroySampler(device, sampler, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
+                                                         const VkAllocationCallbacks *pAllocator,
+                                                         VkDescriptorSetLayout *pSetLayout) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pCreateInfo) {
+            if (pCreateInfo->pBindings) {
+                for (uint32_t idx0 = 0; idx0 < pCreateInfo->bindingCount; ++idx0) {
+                    if (pCreateInfo->pBindings[idx0].pImmutableSamplers) {
+                        for (uint32_t idx1 = 0; idx1 < pCreateInfo->pBindings[idx0].descriptorCount; ++idx1) {
+                            skip_call |=
+                                ValidateNonDispatchableObject(device, pCreateInfo->pBindings[idx0].pImmutableSamplers[idx1],
+                                                              VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, false);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pSetLayout, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
+                                                      const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(device, descriptorSetLayout,
+                                                   VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, descriptorSetLayout, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
+                                                    const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pDescriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
+                                                   VkDescriptorPoolResetFlags flags) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->ResetDescriptorPool(device, descriptorPool, flags);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
+                                                const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount,
+                                                const VkCopyDescriptorSet *pDescriptorCopies) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pDescriptorCopies) {
+            for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
+                if (pDescriptorCopies[idx0].dstSet) {
+                    skip_call |= ValidateNonDispatchableObject(device, pDescriptorCopies[idx0].dstSet,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false);
+                }
+                if (pDescriptorCopies[idx0].srcSet) {
+                    skip_call |= ValidateNonDispatchableObject(device, pDescriptorCopies[idx0].srcSet,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false);
+                }
+            }
+        }
+        if (pDescriptorWrites) {
+            for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
+                if (pDescriptorWrites[idx1].dstSet) {
+                    skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].dstSet,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false);
+                }
+                if ((pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
+                    for (uint32_t idx2 = 0; idx2 < pDescriptorWrites[idx1].descriptorCount; ++idx2) {
+                        if (pDescriptorWrites[idx1].pBufferInfo[idx2].buffer) {
+                            skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].pBufferInfo[idx2].buffer,
+                                                                       VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+                        }
+                    }
+                }
+                if ((pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)) {
+                    for (uint32_t idx3 = 0; idx3 < pDescriptorWrites[idx1].descriptorCount; ++idx3) {
+                        if (pDescriptorWrites[idx1].pImageInfo[idx3].imageView) {
+                            skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].pImageInfo[idx3].imageView,
+                                                                       VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, false);
+                        }
+                        if (pDescriptorWrites[idx1].pImageInfo[idx3].sampler) {
+                            skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].pImageInfo[idx3].sampler,
+                                                                       VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, false);
+                        }
+                    }
+                }
+                if ((pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
+                    for (uint32_t idx4 = 0; idx4 < pDescriptorWrites[idx1].descriptorCount; ++idx4) {
+                        skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].pTexelBufferView[idx4],
+                                                                   VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, true);
+                    }
+                }
+            }
+        }
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, device)
+        ->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
+                                                 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pCreateInfo) {
+            if (pCreateInfo->pAttachments) {
+                for (uint32_t idx0 = 0; idx0 < pCreateInfo->attachmentCount; ++idx0) {
+                    skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->pAttachments[idx0],
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, false);
+                }
+            }
+            if (pCreateInfo->renderPass) {
+                skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->renderPass,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pFramebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, framebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, framebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyFramebuffer(device, framebuffer, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
+                                                const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pRenderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT);
+    }
+    get_dispatch_table(ot_device_table_map, device)->DestroyRenderPass(device, renderPass, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D *pGranularity) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, device)->GetRenderAreaGranularity(device, renderPass, pGranularity);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
+                                                 const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pCommandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->ResetCommandPool(device, commandPool, flags);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL BeginCommandBuffer(VkCommandBuffer command_buffer, const VkCommandBufferBeginInfo *begin_info) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(command_buffer), layer_data_map);
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(command_buffer, command_buffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        if (begin_info) {
+            OBJTRACK_NODE *pNode =
+                device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT][reinterpret_cast<const uint64_t>(command_buffer)];
+            if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY)) {
+                skip_call |= ValidateNonDispatchableObject(command_buffer, begin_info->pInheritanceInfo->framebuffer,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, true);
+                skip_call |= ValidateNonDispatchableObject(command_buffer, begin_info->pInheritanceInfo->renderPass,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, true);
+            }
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, command_buffer)->BeginCommandBuffer(command_buffer, begin_info);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, commandBuffer)->EndCommandBuffer(commandBuffer);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, commandBuffer)->ResetCommandBuffer(commandBuffer, flags);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
+                                           VkPipeline pipeline) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
+                                          const VkViewport *pViewports) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
+                                         const VkRect2D *pScissors) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetLineWidth(commandBuffer, lineWidth);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp,
+                                           float depthBiasSlopeFactor) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetBlendConstants(commandBuffer, blendConstants);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+                                                    uint32_t compareMask) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetStencilReference(commandBuffer, faceMask, reference);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
+                                                 VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount,
+                                                 const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
+                                                 const uint32_t *pDynamicOffsets) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, layout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
+        if (pDescriptorSets) {
+            for (uint32_t idx0 = 0; idx0 < descriptorSetCount; ++idx0) {
+                skip_call |= ValidateNonDispatchableObject(commandBuffer, pDescriptorSets[idx0],
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false);
+            }
+        }
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets,
+                                dynamicOffsetCount, pDynamicOffsets);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
+                                              VkIndexType indexType) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount,
+                                                const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        if (pBuffers) {
+            for (uint32_t idx0 = 0; idx0 < bindingCount; ++idx0) {
+                skip_call |=
+                    ValidateNonDispatchableObject(commandBuffer, pBuffers[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+            }
+        }
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
+                                   uint32_t firstVertex, uint32_t firstInstance) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
+                                          uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount,
+                                           uint32_t stride) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
+                                                  uint32_t drawCount, uint32_t stride) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdDispatch(commandBuffer, x, y, z);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdDispatchIndirect(commandBuffer, buffer, offset);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
+                                         uint32_t regionCount, const VkBufferCopy *pRegions) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+                                        VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
+                                        const VkImageCopy *pRegions) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+                                        VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
+                                        const VkImageBlit *pRegions, VkFilter filter) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
+                                                VkImageLayout dstImageLayout, uint32_t regionCount,
+                                                const VkBufferImageCopy *pRegions) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+                                                VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
+                                           VkDeviceSize dataSize, const uint32_t *pData) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
+                                         VkDeviceSize size, uint32_t data) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
+                                              const VkClearColorValue *pColor, uint32_t rangeCount,
+                                              const VkImageSubresourceRange *pRanges) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
+                                                     const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
+                                                     const VkImageSubresourceRange *pRanges) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
+                                               const VkClearAttachment *pAttachments, uint32_t rectCount,
+                                               const VkClearRect *pRects) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+                                           VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
+                                           const VkImageResolve *pRegions) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdSetEvent(commandBuffer, event, stageMask);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdResetEvent(commandBuffer, event, stageMask);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
+                                         VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
+                                         uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
+                                         uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
+                                         uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        if (pBufferMemoryBarriers) {
+            for (uint32_t idx0 = 0; idx0 < bufferMemoryBarrierCount; ++idx0) {
+                if (pBufferMemoryBarriers[idx0].buffer) {
+                    skip_call |= ValidateNonDispatchableObject(commandBuffer, pBufferMemoryBarriers[idx0].buffer,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+                }
+            }
+        }
+        if (pEvents) {
+            for (uint32_t idx1 = 0; idx1 < eventCount; ++idx1) {
+                skip_call |=
+                    ValidateNonDispatchableObject(commandBuffer, pEvents[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+            }
+        }
+        if (pImageMemoryBarriers) {
+            for (uint32_t idx2 = 0; idx2 < imageMemoryBarrierCount; ++idx2) {
+                if (pImageMemoryBarriers[idx2].image) {
+                    skip_call |= ValidateNonDispatchableObject(commandBuffer, pImageMemoryBarriers[idx2].image,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+                }
+            }
+        }
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers,
+                        bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
+                                              VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
+                                              uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
+                                              uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
+                                              uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        if (pBufferMemoryBarriers) {
+            for (uint32_t idx0 = 0; idx0 < bufferMemoryBarrierCount; ++idx0) {
+                if (pBufferMemoryBarriers[idx0].buffer) {
+                    skip_call |= ValidateNonDispatchableObject(commandBuffer, pBufferMemoryBarriers[idx0].buffer,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+                }
+            }
+        }
+        if (pImageMemoryBarriers) {
+            for (uint32_t idx1 = 0; idx1 < imageMemoryBarrierCount; ++idx1) {
+                if (pImageMemoryBarriers[idx1].image) {
+                    skip_call |= ValidateNonDispatchableObject(commandBuffer, pImageMemoryBarriers[idx1].image,
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+                }
+            }
+        }
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers,
+                             bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query,
+                                         VkQueryControlFlags flags) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdBeginQuery(commandBuffer, queryPool, query, flags);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdEndQuery(commandBuffer, queryPool, query);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery,
+                                             uint32_t queryCount) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
+                                             VkQueryPool queryPool, uint32_t query) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery,
+                                                   uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset,
+                                                   VkDeviceSize stride, VkQueryResultFlags flags) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags,
+                                            uint32_t offset, uint32_t size, const void *pValues) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(commandBuffer, layout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)
+        ->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
+                                              VkSubpassContents contents) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        if (pRenderPassBegin) {
+            skip_call |= ValidateNonDispatchableObject(commandBuffer, pRenderPassBegin->framebuffer,
+                                                       VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, false);
+            skip_call |= ValidateNonDispatchableObject(commandBuffer, pRenderPassBegin->renderPass,
+                                                       VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
+        }
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdNextSubpass(commandBuffer, contents);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdEndRenderPass(commandBuffer);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
+                                              const VkCommandBuffer *pCommandBuffers) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        if (pCommandBuffers) {
+            for (uint32_t idx0 = 0; idx0 < commandBufferCount; ++idx0) {
+                skip_call |= ValidateDispatchableObject(commandBuffer, pCommandBuffers[idx0],
+                                                        VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+            }
+        }
+    }
+    if (skip_call) {
+        return;
+    }
+    get_dispatch_table(ot_device_table_map, commandBuffer)->CmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(instance, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+    }
+    if (skip_call) {
+        return;
+    }
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        DestroyNonDispatchableObject(instance, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+    }
+    get_dispatch_table(ot_instance_table_map, instance)->DestroySurfaceKHR(instance, surface, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
+                                                                  VkSurfaceKHR surface, VkBool32 *pSupported) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+                                                                       VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+                                                                  uint32_t *pSurfaceFormatCount,
+                                                                  VkSurfaceFormatKHR *pSurfaceFormats) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+                                                                       uint32_t *pPresentModeCount,
+                                                                       VkPresentModeKHR *pPresentModes) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+                                                  const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        if (pCreateInfo) {
+            skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->oldSwapchain,
+                                                       VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, true);
+            layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+            skip_call |= ValidateNonDispatchableObject(device_data->physical_device, pCreateInfo->surface,
+                                                       VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+        }
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(device, *pSwapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
+                                                   VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateNonDispatchableObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, true);
+        skip_call |= ValidateNonDispatchableObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, true);
+        skip_call |= ValidateNonDispatchableObject(device, swapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)
+                          ->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (pPresentInfo) {
+            if (pPresentInfo->pSwapchains) {
+                for (uint32_t idx0 = 0; idx0 < pPresentInfo->swapchainCount; ++idx0) {
+                    skip_call |= ValidateNonDispatchableObject(queue, pPresentInfo->pSwapchains[idx0],
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, false);
+                }
+            }
+            if (pPresentInfo->pWaitSemaphores) {
+                for (uint32_t idx1 = 0; idx1 < pPresentInfo->waitSemaphoreCount; ++idx1) {
+                    skip_call |= ValidateNonDispatchableObject(queue, pPresentInfo->pWaitSemaphores[idx1],
+                                                               VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false);
+                }
+            }
+        }
+        skip_call |= ValidateDispatchableObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, queue)->QueuePresentKHR(queue, pPresentInfo);
+    return result;
+}
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+                                                     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_instance_table_map, instance)->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                            uint32_t queueFamilyIndex) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_FALSE;
+    }
+    VkBool32 result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex);
+    return result;
+}
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_instance_table_map, instance)->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                          uint32_t queueFamilyIndex, xcb_connection_t *connection,
+                                                                          xcb_visualid_t visual_id) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_FALSE;
+    }
+    VkBool32 result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection, visual_id);
+    return result;
+}
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
+                                                    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_instance_table_map, instance)->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                           uint32_t queueFamilyIndex, Display *dpy,
+                                                                           VisualID visualID) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_FALSE;
+    }
+    VkBool32 result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, dpy, visualID);
+    return result;
+}
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_instance_table_map, instance)->CreateMirSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                          uint32_t queueFamilyIndex, MirConnection *connection) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_FALSE;
+    }
+    VkBool32 result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceMirPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection);
+    return result;
+}
+#endif // VK_USE_PLATFORM_MIR_KHR
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
+                                                       const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_instance_table_map, instance)->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                              uint32_t queueFamilyIndex,
+                                                                              struct wl_display *display) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |=
+            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_FALSE;
+    }
+    VkBool32 result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, display);
+    return result;
+}
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
+                                                       const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result =
+        get_dispatch_table(ot_instance_table_map, instance)->CreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (result == VK_SUCCESS) {
+            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+        }
+    }
+    return result;
+}
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
+                                                            const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+                                                            const VkAllocationCallbacks *pAllocator,
+                                                            VkDebugReportCallbackEXT *pCallback) {
+    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
+    VkResult result = pInstanceTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
+    if (VK_SUCCESS == result) {
+        layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+        result = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pCallback);
+        CreateNonDispatchableObject(instance, *pCallback, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT);
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
+                                                         const VkAllocationCallbacks *pAllocator) {
+    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
+    pInstanceTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    layer_destroy_msg_callback(instance_data->report_data, msgCallback, pAllocator);
+    DestroyNonDispatchableObject(instance, msgCallback, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT);
+}
+
+VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+                                                 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+                                                 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
+    pInstanceTable->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
+}
+
+static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
+
+static const VkLayerProperties globalLayerProps = {"VK_LAYER_LUNARG_object_tracker",
+                                                   VK_LAYER_API_VERSION, // specVersion
+                                                   1,                    // implementationVersion
+                                                   "LunarG Validation Layer"};
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
+                                                              VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
+                                                                    VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))
+        return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
+
+    return VK_ERROR_LAYER_NOT_PRESENT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
+                                                                  uint32_t *pCount, VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))
+        return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
+
+    assert(physicalDevice);
+    VkLayerInstanceDispatchTable *pTable = get_dispatch_table(ot_instance_table_map, physicalDevice);
+    return pTable->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
+}
+
+static inline PFN_vkVoidFunction InterceptMsgCallbackGetProcAddrCommand(const char *name, VkInstance instance) {
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    return debug_report_get_instance_proc_addr(instance_data->report_data, name);
+}
+
+static inline PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkInstance instance) {
+    VkLayerInstanceDispatchTable *pTable = get_dispatch_table(ot_instance_table_map, instance);
+    if (instanceExtMap.size() == 0 || !instanceExtMap[pTable].wsi_enabled)
+        return nullptr;
+
+    if (!strcmp("vkDestroySurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR);
+    if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR);
+    if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR);
+    if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR);
+    if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR);
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    if ((instanceExtMap[pTable].win32_enabled == true) && !strcmp("vkCreateWin32SurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateWin32SurfaceKHR);
+    if ((instanceExtMap[pTable].win32_enabled == true) && !strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWin32PresentationSupportKHR);
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    if ((instanceExtMap[pTable].xcb_enabled == true) && !strcmp("vkCreateXcbSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateXcbSurfaceKHR);
+    if ((instanceExtMap[pTable].xcb_enabled == true) && !strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXcbPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    if ((instanceExtMap[pTable].xlib_enabled == true) && !strcmp("vkCreateXlibSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateXlibSurfaceKHR);
+    if ((instanceExtMap[pTable].xlib_enabled == true) && !strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXlibPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    if ((instanceExtMap[pTable].mir_enabled == true) && !strcmp("vkCreateMirSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateMirSurfaceKHR);
+    if ((instanceExtMap[pTable].mir_enabled == true) && !strcmp("vkGetPhysicalDeviceMirPresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMirPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_MIR_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    if ((instanceExtMap[pTable].wayland_enabled == true) && !strcmp("vkCreateWaylandSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateWaylandSurfaceKHR);
+    if ((instanceExtMap[pTable].wayland_enabled == true) && !strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWaylandPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+    if ((instanceExtMap[pTable].android_enabled == true) && !strcmp("vkCreateAndroidSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR);
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+    return nullptr;
+}
+
+static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    device_data->wsi_enabled = false;
+
+    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
+            device_data->wsi_enabled = true;
+        }
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0) {
+            device_data->objtrack_extensions_enabled = true;
+        }
+    }
+}
+
+static void CheckInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
+    VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(ot_instance_table_map, instance);
+ 
+
+    instanceExtMap[pDisp] = {};
+
+    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
+            instanceExtMap[pDisp].wsi_enabled = true;
+        }
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
+            instanceExtMap[pDisp].xlib_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
+            instanceExtMap[pDisp].xcb_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
+            instanceExtMap[pDisp].wayland_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_MIR_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
+            instanceExtMap[pDisp].mir_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
+            instanceExtMap[pDisp].android_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
+            instanceExtMap[pDisp].win32_enabled = true;
+        }
+#endif
+    }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
+                                            const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
+    std::lock_guard<std::mutex> lock(global_lock);
+    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+    assert(chain_info->u.pLayerInfo);
+    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(phy_dev_data->instance, "vkCreateDevice");
+    if (fpCreateDevice == NULL) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
+    // Advance the link info for the next element on the chain
+    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+    VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+    if (result != VK_SUCCESS) {
+        return result;
+    }
+
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+    device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice);
+
+    // Add link back to physDev
+    device_data->physical_device = physicalDevice;
+
+    initDeviceTable(*pDevice, fpGetDeviceProcAddr, ot_device_table_map);
+
+    CheckDeviceRegisterExtensions(pCreateInfo, *pDevice);
+    CreateDispatchableObject(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
+
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
+                                                                  uint32_t *pQueueFamilyPropertyCount,
+                                                                  VkQueueFamilyProperties *pQueueFamilyProperties) {
+    get_dispatch_table(ot_instance_table_map, physicalDevice)
+        ->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
+    std::lock_guard<std::mutex> lock(global_lock);
+    if (pQueueFamilyProperties != NULL) {
+        layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+        for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
+            instance_data->queue_family_properties.emplace_back(pQueueFamilyProperties[i]);
+        }
+    }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
+                                              VkInstance *pInstance) {
+    VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+    assert(chain_info->u.pLayerInfo);
+    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+    if (fpCreateInstance == NULL) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
+    // Advance the link info for the next element on the chain
+    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+    VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+    if (result != VK_SUCCESS) {
+        return result;
+    }
+
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+    instance_data->instance = *pInstance;
+    initInstanceTable(*pInstance, fpGetInstanceProcAddr, ot_instance_table_map);
+    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, *pInstance);
+
+    // Look for one or more debug report create info structures, and copy the
+    // callback(s) for each one found (for use by vkDestroyInstance)
+    layer_copy_tmp_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_callbacks, &instance_data->tmp_dbg_create_infos,
+                             &instance_data->tmp_callbacks);
+
+    instance_data->report_data = debug_report_create_instance(pInstanceTable, *pInstance, pCreateInfo->enabledExtensionCount,
+                                                              pCreateInfo->ppEnabledExtensionNames);
+
+    InitObjectTracker(instance_data, pAllocator);
+    CheckInstanceRegisterExtensions(pCreateInfo, *pInstance);
+
+    CreateDispatchableObject(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
+                                                        VkPhysicalDevice *pPhysicalDevices) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    lock.unlock();
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_instance_table_map, instance)
+                          ->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
+    lock.lock();
+    if (result == VK_SUCCESS) {
+        if (pPhysicalDevices) {
+            for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
+                CreateDispatchableObject(instance, pPhysicalDevices[i], VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT);
+            }
+        }
+    }
+    lock.unlock();
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
+    std::unique_lock<std::mutex> lock(global_lock);
+    ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    lock.unlock();
+
+    get_dispatch_table(ot_device_table_map, device)->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
+
+    lock.lock();
+
+    CreateQueue(device, *pQueue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT);
+    AddQueueInfo(device, queueFamilyIndex, *pQueue);
+}
+
+VKAPI_ATTR void VKAPI_CALL FreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator) {
+    std::unique_lock<std::mutex> lock(global_lock);
+    ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    lock.unlock();
+
+    get_dispatch_table(ot_device_table_map, device)->FreeMemory(device, memory, pAllocator);
+
+    lock.lock();
+    DestroyNonDispatchableObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL MapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size,
+                                         VkMemoryMapFlags flags, void **ppData) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    lock.unlock();
+    if (skip_call == VK_TRUE) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->MapMemory(device, memory, offset, size, flags, ppData);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory memory) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    lock.unlock();
+    if (skip_call == VK_TRUE) {
+        return;
+    }
+
+    get_dispatch_table(ot_device_table_map, device)->UnmapMemory(device, memory);
+}
+VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo,
+                                               VkFence fence) {
+    std::unique_lock<std::mutex> lock(global_lock);
+    ValidateQueueFlags(queue, "QueueBindSparse");
+
+    for (uint32_t i = 0; i < bindInfoCount; i++) {
+        for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
+            ValidateNonDispatchableObject(queue, pBindInfo[i].pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
+                                          false);
+        for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
+            ValidateNonDispatchableObject(queue, pBindInfo[i].pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                                          false);
+        for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
+            ValidateNonDispatchableObject(queue, pBindInfo[i].pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+    }
+    lock.unlock();
+
+    VkResult result = get_dispatch_table(ot_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
+                                                      VkCommandBuffer *pCommandBuffers) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |=
+        ValidateNonDispatchableObject(device, pAllocateInfo->commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
+    lock.unlock();
+
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
+
+    lock.lock();
+    for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
+        AllocateCommandBuffer(device, pAllocateInfo->commandPool, pCommandBuffers[i],
+                              VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, pAllocateInfo->level);
+    }
+    lock.unlock();
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
+                                                      VkDescriptorSet *pDescriptorSets) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateNonDispatchableObject(device, pAllocateInfo->descriptorPool,
+                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
+    for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
+        skip_call |= ValidateNonDispatchableObject(device, pAllocateInfo->pSetLayouts[i],
+                                                   VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
+    }
+    lock.unlock();
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+
+    VkResult result =
+        get_dispatch_table(ot_device_table_map, device)->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
+
+    if (VK_SUCCESS == result) {
+        lock.lock();
+        for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
+            AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i],
+                                  VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
+        }
+        lock.unlock();
+    }
+
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
+                                              const VkCommandBuffer *pCommandBuffers) {
+    bool skip_call = false;
+    std::unique_lock<std::mutex> lock(global_lock);
+    ValidateNonDispatchableObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
+    ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    for (uint32_t i = 0; i < commandBufferCount; i++) {
+        skip_call |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
+    }
+
+    for (uint32_t i = 0; i < commandBufferCount; i++) {
+        DestroyDispatchableObject(device, pCommandBuffers[i], VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT);
+    }
+
+    lock.unlock();
+    if (!skip_call) {
+        get_dispatch_table(ot_device_table_map, device)
+            ->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
+    }
+}
+VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    // A swapchain's images are implicitly deleted when the swapchain is deleted.
+    // Remove this swapchain's images from our map of such images.
+    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = device_data->swapchainImageMap.begin();
+    while (itr != device_data->swapchainImageMap.end()) {
+        OBJTRACK_NODE *pNode = (*itr).second;
+        if (pNode->parent_object == reinterpret_cast<uint64_t &>(swapchain)) {
+            delete pNode;
+            auto delete_item = itr++;
+            device_data->swapchainImageMap.erase(delete_item);
+        } else {
+            ++itr;
+        }
+    }
+    DestroyNonDispatchableObject(device, swapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+    lock.unlock();
+
+    get_dispatch_table(ot_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
+                                                  const VkDescriptorSet *pDescriptorSets) {
+    bool skip_call = false;
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateNonDispatchableObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    for (uint32_t i = 0; i < descriptorSetCount; i++) {
+        skip_call |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
+    }
+
+    for (uint32_t i = 0; i < descriptorSetCount; i++) {
+        DestroyNonDispatchableObject(device, pDescriptorSets[i], VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
+    }
+
+    lock.unlock();
+    if (!skip_call) {
+        result = get_dispatch_table(ot_device_table_map, device)
+                     ->FreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets);
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
+                                                 const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = VK_FALSE;
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateNonDispatchableObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
+    lock.unlock();
+    if (skip_call) {
+        return;
+    }
+    // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
+    // Remove this pool's descriptor sets from our descriptorSet map.
+    lock.lock();
+    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr =
+        device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT].begin();
+    while (itr != device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT].end()) {
+        OBJTRACK_NODE *pNode = (*itr).second;
+        auto del_itr = itr++;
+        if (pNode->parent_object == reinterpret_cast<uint64_t &>(descriptorPool)) {
+            DestroyNonDispatchableObject(device, (VkDescriptorSet)((*del_itr).first),
+                                         VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
+        }
+    }
+    DestroyNonDispatchableObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT);
+    lock.unlock();
+    get_dispatch_table(ot_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    bool skip_call = false;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateNonDispatchableObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
+    lock.unlock();
+    if (skip_call) {
+        return;
+    }
+    lock.lock();
+    // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
+    // Remove this pool's cmdBuffers from our cmd buffer map.
+    auto itr = device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT].begin();
+    auto del_itr = itr;
+    while (itr != device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT].end()) {
+        OBJTRACK_NODE *pNode = (*itr).second;
+        del_itr = itr++;
+        if (pNode->parent_object == reinterpret_cast<uint64_t &>(commandPool)) {
+            skip_call |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
+            DestroyDispatchableObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
+                                      VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT);
+        }
+    }
+    DestroyNonDispatchableObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT);
+    lock.unlock();
+    get_dispatch_table(ot_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
+                                                     VkImage *pSwapchainImages) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    lock.unlock();
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)
+                          ->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
+    if (pSwapchainImages != NULL) {
+        lock.lock();
+        for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
+            CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
+        }
+        lock.unlock();
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
+                                                       const VkGraphicsPipelineCreateInfo *pCreateInfos,
+                                                       const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    if (pCreateInfos) {
+        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
+            if (pCreateInfos[idx0].basePipelineHandle) {
+                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].basePipelineHandle,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
+            }
+            if (pCreateInfos[idx0].layout) {
+                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].layout,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
+            }
+            if (pCreateInfos[idx0].pStages) {
+                for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
+                    if (pCreateInfos[idx0].pStages[idx1].module) {
+                        skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].pStages[idx1].module,
+                                                                   VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
+                    }
+                }
+            }
+            if (pCreateInfos[idx0].renderPass) {
+                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].renderPass,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
+            }
+        }
+    }
+    if (pipelineCache) {
+        skip_call |= ValidateNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+    }
+    lock.unlock();
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)
+                          ->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+    lock.lock();
+    if (result == VK_SUCCESS) {
+        for (uint32_t idx2 = 0; idx2 < createInfoCount; ++idx2) {
+            CreateNonDispatchableObject(device, pPipelines[idx2], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
+        }
+    }
+    lock.unlock();
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
+                                                      const VkComputePipelineCreateInfo *pCreateInfos,
+                                                      const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    if (pCreateInfos) {
+        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
+            if (pCreateInfos[idx0].basePipelineHandle) {
+                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].basePipelineHandle,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
+            }
+            if (pCreateInfos[idx0].layout) {
+                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].layout,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
+            }
+            if (pCreateInfos[idx0].stage.module) {
+                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].stage.module,
+                                                           VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
+            }
+        }
+    }
+    if (pipelineCache) {
+        skip_call |= ValidateNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+    }
+    lock.unlock();
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)
+                          ->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+    lock.lock();
+    if (result == VK_SUCCESS) {
+        for (uint32_t idx1 = 0; idx1 < createInfoCount; ++idx1) {
+            CreateNonDispatchableObject(device, pPipelines[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
+        }
+    }
+    lock.unlock();
+    return result;
+}
+
+static inline PFN_vkVoidFunction InterceptCoreDeviceCommand(const char *name) {
+    if (!name || name[0] != 'v' || name[1] != 'k')
+        return NULL;
+
+    name += 2;
+    if (!strcmp(name, "GetDeviceProcAddr"))
+        return (PFN_vkVoidFunction)GetDeviceProcAddr;
+    if (!strcmp(name, "DestroyDevice"))
+        return (PFN_vkVoidFunction)DestroyDevice;
+    if (!strcmp(name, "GetDeviceQueue"))
+        return (PFN_vkVoidFunction)GetDeviceQueue;
+    if (!strcmp(name, "QueueSubmit"))
+        return (PFN_vkVoidFunction)QueueSubmit;
+    if (!strcmp(name, "QueueWaitIdle"))
+        return (PFN_vkVoidFunction)QueueWaitIdle;
+    if (!strcmp(name, "DeviceWaitIdle"))
+        return (PFN_vkVoidFunction)DeviceWaitIdle;
+    if (!strcmp(name, "AllocateMemory"))
+        return (PFN_vkVoidFunction)AllocateMemory;
+    if (!strcmp(name, "FreeMemory"))
+        return (PFN_vkVoidFunction)FreeMemory;
+    if (!strcmp(name, "MapMemory"))
+        return (PFN_vkVoidFunction)MapMemory;
+    if (!strcmp(name, "UnmapMemory"))
+        return (PFN_vkVoidFunction)UnmapMemory;
+    if (!strcmp(name, "FlushMappedMemoryRanges"))
+        return (PFN_vkVoidFunction)FlushMappedMemoryRanges;
+    if (!strcmp(name, "InvalidateMappedMemoryRanges"))
+        return (PFN_vkVoidFunction)InvalidateMappedMemoryRanges;
+    if (!strcmp(name, "GetDeviceMemoryCommitment"))
+        return (PFN_vkVoidFunction)GetDeviceMemoryCommitment;
+    if (!strcmp(name, "BindBufferMemory"))
+        return (PFN_vkVoidFunction)BindBufferMemory;
+    if (!strcmp(name, "BindImageMemory"))
+        return (PFN_vkVoidFunction)BindImageMemory;
+    if (!strcmp(name, "GetBufferMemoryRequirements"))
+        return (PFN_vkVoidFunction)GetBufferMemoryRequirements;
+    if (!strcmp(name, "GetImageMemoryRequirements"))
+        return (PFN_vkVoidFunction)GetImageMemoryRequirements;
+    if (!strcmp(name, "GetImageSparseMemoryRequirements"))
+        return (PFN_vkVoidFunction)GetImageSparseMemoryRequirements;
+    if (!strcmp(name, "QueueBindSparse"))
+        return (PFN_vkVoidFunction)QueueBindSparse;
+    if (!strcmp(name, "CreateFence"))
+        return (PFN_vkVoidFunction)CreateFence;
+    if (!strcmp(name, "DestroyFence"))
+        return (PFN_vkVoidFunction)DestroyFence;
+    if (!strcmp(name, "ResetFences"))
+        return (PFN_vkVoidFunction)ResetFences;
+    if (!strcmp(name, "GetFenceStatus"))
+        return (PFN_vkVoidFunction)GetFenceStatus;
+    if (!strcmp(name, "WaitForFences"))
+        return (PFN_vkVoidFunction)WaitForFences;
+    if (!strcmp(name, "CreateSemaphore"))
+        return (PFN_vkVoidFunction)CreateSemaphore;
+    if (!strcmp(name, "DestroySemaphore"))
+        return (PFN_vkVoidFunction)DestroySemaphore;
+    if (!strcmp(name, "CreateEvent"))
+        return (PFN_vkVoidFunction)CreateEvent;
+    if (!strcmp(name, "DestroyEvent"))
+        return (PFN_vkVoidFunction)DestroyEvent;
+    if (!strcmp(name, "GetEventStatus"))
+        return (PFN_vkVoidFunction)GetEventStatus;
+    if (!strcmp(name, "SetEvent"))
+        return (PFN_vkVoidFunction)SetEvent;
+    if (!strcmp(name, "ResetEvent"))
+        return (PFN_vkVoidFunction)ResetEvent;
+    if (!strcmp(name, "CreateQueryPool"))
+        return (PFN_vkVoidFunction)CreateQueryPool;
+    if (!strcmp(name, "DestroyQueryPool"))
+        return (PFN_vkVoidFunction)DestroyQueryPool;
+    if (!strcmp(name, "GetQueryPoolResults"))
+        return (PFN_vkVoidFunction)GetQueryPoolResults;
+    if (!strcmp(name, "CreateBuffer"))
+        return (PFN_vkVoidFunction)CreateBuffer;
+    if (!strcmp(name, "DestroyBuffer"))
+        return (PFN_vkVoidFunction)DestroyBuffer;
+    if (!strcmp(name, "CreateBufferView"))
+        return (PFN_vkVoidFunction)CreateBufferView;
+    if (!strcmp(name, "DestroyBufferView"))
+        return (PFN_vkVoidFunction)DestroyBufferView;
+    if (!strcmp(name, "CreateImage"))
+        return (PFN_vkVoidFunction)CreateImage;
+    if (!strcmp(name, "DestroyImage"))
+        return (PFN_vkVoidFunction)DestroyImage;
+    if (!strcmp(name, "GetImageSubresourceLayout"))
+        return (PFN_vkVoidFunction)GetImageSubresourceLayout;
+    if (!strcmp(name, "CreateImageView"))
+        return (PFN_vkVoidFunction)CreateImageView;
+    if (!strcmp(name, "DestroyImageView"))
+        return (PFN_vkVoidFunction)DestroyImageView;
+    if (!strcmp(name, "CreateShaderModule"))
+        return (PFN_vkVoidFunction)CreateShaderModule;
+    if (!strcmp(name, "DestroyShaderModule"))
+        return (PFN_vkVoidFunction)DestroyShaderModule;
+    if (!strcmp(name, "CreatePipelineCache"))
+        return (PFN_vkVoidFunction)CreatePipelineCache;
+    if (!strcmp(name, "DestroyPipelineCache"))
+        return (PFN_vkVoidFunction)DestroyPipelineCache;
+    if (!strcmp(name, "GetPipelineCacheData"))
+        return (PFN_vkVoidFunction)GetPipelineCacheData;
+    if (!strcmp(name, "MergePipelineCaches"))
+        return (PFN_vkVoidFunction)MergePipelineCaches;
+    if (!strcmp(name, "CreateGraphicsPipelines"))
+        return (PFN_vkVoidFunction)CreateGraphicsPipelines;
+    if (!strcmp(name, "CreateComputePipelines"))
+        return (PFN_vkVoidFunction)CreateComputePipelines;
+    if (!strcmp(name, "DestroyPipeline"))
+        return (PFN_vkVoidFunction)DestroyPipeline;
+    if (!strcmp(name, "CreatePipelineLayout"))
+        return (PFN_vkVoidFunction)CreatePipelineLayout;
+    if (!strcmp(name, "DestroyPipelineLayout"))
+        return (PFN_vkVoidFunction)DestroyPipelineLayout;
+    if (!strcmp(name, "CreateSampler"))
+        return (PFN_vkVoidFunction)CreateSampler;
+    if (!strcmp(name, "DestroySampler"))
+        return (PFN_vkVoidFunction)DestroySampler;
+    if (!strcmp(name, "CreateDescriptorSetLayout"))
+        return (PFN_vkVoidFunction)CreateDescriptorSetLayout;
+    if (!strcmp(name, "DestroyDescriptorSetLayout"))
+        return (PFN_vkVoidFunction)DestroyDescriptorSetLayout;
+    if (!strcmp(name, "CreateDescriptorPool"))
+        return (PFN_vkVoidFunction)CreateDescriptorPool;
+    if (!strcmp(name, "DestroyDescriptorPool"))
+        return (PFN_vkVoidFunction)DestroyDescriptorPool;
+    if (!strcmp(name, "ResetDescriptorPool"))
+        return (PFN_vkVoidFunction)ResetDescriptorPool;
+    if (!strcmp(name, "AllocateDescriptorSets"))
+        return (PFN_vkVoidFunction)AllocateDescriptorSets;
+    if (!strcmp(name, "FreeDescriptorSets"))
+        return (PFN_vkVoidFunction)FreeDescriptorSets;
+    if (!strcmp(name, "UpdateDescriptorSets"))
+        return (PFN_vkVoidFunction)UpdateDescriptorSets;
+    if (!strcmp(name, "CreateFramebuffer"))
+        return (PFN_vkVoidFunction)CreateFramebuffer;
+    if (!strcmp(name, "DestroyFramebuffer"))
+        return (PFN_vkVoidFunction)DestroyFramebuffer;
+    if (!strcmp(name, "CreateRenderPass"))
+        return (PFN_vkVoidFunction)CreateRenderPass;
+    if (!strcmp(name, "DestroyRenderPass"))
+        return (PFN_vkVoidFunction)DestroyRenderPass;
+    if (!strcmp(name, "GetRenderAreaGranularity"))
+        return (PFN_vkVoidFunction)GetRenderAreaGranularity;
+    if (!strcmp(name, "CreateCommandPool"))
+        return (PFN_vkVoidFunction)CreateCommandPool;
+    if (!strcmp(name, "DestroyCommandPool"))
+        return (PFN_vkVoidFunction)DestroyCommandPool;
+    if (!strcmp(name, "ResetCommandPool"))
+        return (PFN_vkVoidFunction)ResetCommandPool;
+    if (!strcmp(name, "AllocateCommandBuffers"))
+        return (PFN_vkVoidFunction)AllocateCommandBuffers;
+    if (!strcmp(name, "FreeCommandBuffers"))
+        return (PFN_vkVoidFunction)FreeCommandBuffers;
+    if (!strcmp(name, "BeginCommandBuffer"))
+        return (PFN_vkVoidFunction)BeginCommandBuffer;
+    if (!strcmp(name, "EndCommandBuffer"))
+        return (PFN_vkVoidFunction)EndCommandBuffer;
+    if (!strcmp(name, "ResetCommandBuffer"))
+        return (PFN_vkVoidFunction)ResetCommandBuffer;
+    if (!strcmp(name, "CmdBindPipeline"))
+        return (PFN_vkVoidFunction)CmdBindPipeline;
+    if (!strcmp(name, "CmdSetViewport"))
+        return (PFN_vkVoidFunction)CmdSetViewport;
+    if (!strcmp(name, "CmdSetScissor"))
+        return (PFN_vkVoidFunction)CmdSetScissor;
+    if (!strcmp(name, "CmdSetLineWidth"))
+        return (PFN_vkVoidFunction)CmdSetLineWidth;
+    if (!strcmp(name, "CmdSetDepthBias"))
+        return (PFN_vkVoidFunction)CmdSetDepthBias;
+    if (!strcmp(name, "CmdSetBlendConstants"))
+        return (PFN_vkVoidFunction)CmdSetBlendConstants;
+    if (!strcmp(name, "CmdSetDepthBounds"))
+        return (PFN_vkVoidFunction)CmdSetDepthBounds;
+    if (!strcmp(name, "CmdSetStencilCompareMask"))
+        return (PFN_vkVoidFunction)CmdSetStencilCompareMask;
+    if (!strcmp(name, "CmdSetStencilWriteMask"))
+        return (PFN_vkVoidFunction)CmdSetStencilWriteMask;
+    if (!strcmp(name, "CmdSetStencilReference"))
+        return (PFN_vkVoidFunction)CmdSetStencilReference;
+    if (!strcmp(name, "CmdBindDescriptorSets"))
+        return (PFN_vkVoidFunction)CmdBindDescriptorSets;
+    if (!strcmp(name, "CmdBindIndexBuffer"))
+        return (PFN_vkVoidFunction)CmdBindIndexBuffer;
+    if (!strcmp(name, "CmdBindVertexBuffers"))
+        return (PFN_vkVoidFunction)CmdBindVertexBuffers;
+    if (!strcmp(name, "CmdDraw"))
+        return (PFN_vkVoidFunction)CmdDraw;
+    if (!strcmp(name, "CmdDrawIndexed"))
+        return (PFN_vkVoidFunction)CmdDrawIndexed;
+    if (!strcmp(name, "CmdDrawIndirect"))
+        return (PFN_vkVoidFunction)CmdDrawIndirect;
+    if (!strcmp(name, "CmdDrawIndexedIndirect"))
+        return (PFN_vkVoidFunction)CmdDrawIndexedIndirect;
+    if (!strcmp(name, "CmdDispatch"))
+        return (PFN_vkVoidFunction)CmdDispatch;
+    if (!strcmp(name, "CmdDispatchIndirect"))
+        return (PFN_vkVoidFunction)CmdDispatchIndirect;
+    if (!strcmp(name, "CmdCopyBuffer"))
+        return (PFN_vkVoidFunction)CmdCopyBuffer;
+    if (!strcmp(name, "CmdCopyImage"))
+        return (PFN_vkVoidFunction)CmdCopyImage;
+    if (!strcmp(name, "CmdBlitImage"))
+        return (PFN_vkVoidFunction)CmdBlitImage;
+    if (!strcmp(name, "CmdCopyBufferToImage"))
+        return (PFN_vkVoidFunction)CmdCopyBufferToImage;
+    if (!strcmp(name, "CmdCopyImageToBuffer"))
+        return (PFN_vkVoidFunction)CmdCopyImageToBuffer;
+    if (!strcmp(name, "CmdUpdateBuffer"))
+        return (PFN_vkVoidFunction)CmdUpdateBuffer;
+    if (!strcmp(name, "CmdFillBuffer"))
+        return (PFN_vkVoidFunction)CmdFillBuffer;
+    if (!strcmp(name, "CmdClearColorImage"))
+        return (PFN_vkVoidFunction)CmdClearColorImage;
+    if (!strcmp(name, "CmdClearDepthStencilImage"))
+        return (PFN_vkVoidFunction)CmdClearDepthStencilImage;
+    if (!strcmp(name, "CmdClearAttachments"))
+        return (PFN_vkVoidFunction)CmdClearAttachments;
+    if (!strcmp(name, "CmdResolveImage"))
+        return (PFN_vkVoidFunction)CmdResolveImage;
+    if (!strcmp(name, "CmdSetEvent"))
+        return (PFN_vkVoidFunction)CmdSetEvent;
+    if (!strcmp(name, "CmdResetEvent"))
+        return (PFN_vkVoidFunction)CmdResetEvent;
+    if (!strcmp(name, "CmdWaitEvents"))
+        return (PFN_vkVoidFunction)CmdWaitEvents;
+    if (!strcmp(name, "CmdPipelineBarrier"))
+        return (PFN_vkVoidFunction)CmdPipelineBarrier;
+    if (!strcmp(name, "CmdBeginQuery"))
+        return (PFN_vkVoidFunction)CmdBeginQuery;
+    if (!strcmp(name, "CmdEndQuery"))
+        return (PFN_vkVoidFunction)CmdEndQuery;
+    if (!strcmp(name, "CmdResetQueryPool"))
+        return (PFN_vkVoidFunction)CmdResetQueryPool;
+    if (!strcmp(name, "CmdWriteTimestamp"))
+        return (PFN_vkVoidFunction)CmdWriteTimestamp;
+    if (!strcmp(name, "CmdCopyQueryPoolResults"))
+        return (PFN_vkVoidFunction)CmdCopyQueryPoolResults;
+    if (!strcmp(name, "CmdPushConstants"))
+        return (PFN_vkVoidFunction)CmdPushConstants;
+    if (!strcmp(name, "CmdBeginRenderPass"))
+        return (PFN_vkVoidFunction)CmdBeginRenderPass;
+    if (!strcmp(name, "CmdNextSubpass"))
+        return (PFN_vkVoidFunction)CmdNextSubpass;
+    if (!strcmp(name, "CmdEndRenderPass"))
+        return (PFN_vkVoidFunction)CmdEndRenderPass;
+    if (!strcmp(name, "CmdExecuteCommands"))
+        return (PFN_vkVoidFunction)CmdExecuteCommands;
+
+    return NULL;
+}
+static inline PFN_vkVoidFunction InterceptCoreInstanceCommand(const char *name) {
+    if (!name || name[0] != 'v' || name[1] != 'k')
+        return NULL;
+
+    name += 2;
+    if (!strcmp(name, "CreateInstance"))
+        return (PFN_vkVoidFunction)CreateInstance;
+    if (!strcmp(name, "DestroyInstance"))
+        return (PFN_vkVoidFunction)DestroyInstance;
+    if (!strcmp(name, "EnumeratePhysicalDevices"))
+        return (PFN_vkVoidFunction)EnumeratePhysicalDevices;
+    if (!strcmp(name, "GetPhysicalDeviceFeatures"))
+        return (PFN_vkVoidFunction)GetPhysicalDeviceFeatures;
+    if (!strcmp(name, "GetPhysicalDeviceFormatProperties"))
+        return (PFN_vkVoidFunction)GetPhysicalDeviceFormatProperties;
+    if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties"))
+        return (PFN_vkVoidFunction)GetPhysicalDeviceImageFormatProperties;
+    if (!strcmp(name, "GetPhysicalDeviceProperties"))
+        return (PFN_vkVoidFunction)GetPhysicalDeviceProperties;
+    if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties"))
+        return (PFN_vkVoidFunction)GetPhysicalDeviceQueueFamilyProperties;
+    if (!strcmp(name, "GetPhysicalDeviceMemoryProperties"))
+        return (PFN_vkVoidFunction)GetPhysicalDeviceMemoryProperties;
+    if (!strcmp(name, "GetInstanceProcAddr"))
+        return (PFN_vkVoidFunction)GetInstanceProcAddr;
+    if (!strcmp(name, "CreateDevice"))
+        return (PFN_vkVoidFunction)CreateDevice;
+    if (!strcmp(name, "EnumerateInstanceExtensionProperties"))
+        return (PFN_vkVoidFunction)EnumerateInstanceExtensionProperties;
+    if (!strcmp(name, "EnumerateInstanceLayerProperties"))
+        return (PFN_vkVoidFunction)EnumerateInstanceLayerProperties;
+    if (!strcmp(name, "EnumerateDeviceLayerProperties"))
+        return (PFN_vkVoidFunction)EnumerateDeviceLayerProperties;
+    if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties"))
+        return (PFN_vkVoidFunction)GetPhysicalDeviceSparseImageFormatProperties;
+
+    return NULL;
+}
+
+static inline PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkDevice device) {
+    if (device) {
+        layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+        if (!device_data->wsi_enabled)
+            return nullptr;
+    }
+    if (!strcmp("vkCreateSwapchainKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR);
+    if (!strcmp("vkDestroySwapchainKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR);
+    if (!strcmp("vkGetSwapchainImagesKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR);
+    if (!strcmp("vkAcquireNextImageKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR);
+    if (!strcmp("vkQueuePresentKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR);
+
+    return nullptr;
+}
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
+    PFN_vkVoidFunction addr;
+    addr = InterceptCoreDeviceCommand(funcName);
+    if (addr) {
+        return addr;
+    }
+    assert(device);
+
+    addr = InterceptWsiEnabledCommand(funcName, device);
+    if (addr) {
+        return addr;
+    }
+    if (get_dispatch_table(ot_device_table_map, device)->GetDeviceProcAddr == NULL) {
+        return NULL;
+    }
+    return get_dispatch_table(ot_device_table_map, device)->GetDeviceProcAddr(device, funcName);
+}
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
+    PFN_vkVoidFunction addr;
+    addr = InterceptCoreInstanceCommand(funcName);
+    if (!addr) {
+        addr = InterceptCoreDeviceCommand(funcName);
+    }
+    if (!addr) {
+        addr = InterceptWsiEnabledCommand(funcName, VkDevice(VK_NULL_HANDLE));
+    }
+    if (addr) {
+        return addr;
+    }
+    assert(instance);
+
+    addr = InterceptMsgCallbackGetProcAddrCommand(funcName, instance);
+    if (addr) {
+        return addr;
+    }
+    addr = InterceptWsiEnabledCommand(funcName, instance);
+    if (addr) {
+        return addr;
+    }
+    if (get_dispatch_table(ot_instance_table_map, instance)->GetInstanceProcAddr == NULL) {
+        return NULL;
+    }
+    return get_dispatch_table(ot_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
+}
+
+} // namespace object_tracker
+
+// vk_layer_logging.h expects these to be defined
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instance,
+                                                              const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+                                                              const VkAllocationCallbacks *pAllocator,
+                                                              VkDebugReportCallbackEXT *pMsgCallback) {
+    return object_tracker::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
+                                                           const VkAllocationCallbacks *pAllocator) {
+    object_tracker::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+                                                   VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+                                                   int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+    object_tracker::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
+}
+
+// Loader-layer interface v0, just wrappers since there is only a layer
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
+                                                                                      VkExtensionProperties *pProperties) {
+    return object_tracker::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
+                                                                                  VkLayerProperties *pProperties) {
+    return object_tracker::EnumerateInstanceLayerProperties(pCount, pProperties);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
+                                                                                VkLayerProperties *pProperties) {
+    // The layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return object_tracker::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
+    return object_tracker::GetDeviceProcAddr(dev, funcName);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
+    return object_tracker::GetInstanceProcAddr(instance, funcName);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
+                                                                                    const char *pLayerName, uint32_t *pCount,
+                                                                                    VkExtensionProperties *pProperties) {
+    // The layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return object_tracker::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
+}
diff --git a/layers/object_tracker.h b/layers/object_tracker.h
index 333775a..8f514a6 100644
--- a/layers/object_tracker.h
+++ b/layers/object_tracker.h
@@ -15,18 +15,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * Author: Jon Ashburn <jon@lunarg.com>
  * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
  * Author: Tobin Ehlis <tobin@lunarg.com>
  */
 
 #include <mutex>
 
-#include "vulkan/vk_layer.h"
-#include "vk_layer_extension_utils.h"
 #include "vk_enum_string_helper.h"
+#include "vk_layer_extension_utils.h"
 #include "vk_layer_table.h"
 #include "vk_layer_utils.h"
+#include "vulkan/vk_layer.h"
 
 namespace object_tracker {
 
@@ -54,1013 +54,110 @@
     OBJSTATUS_COMMAND_BUFFER_SECONDARY = 0x00000040, // Command Buffer is of type SECONDARY
 };
 
+// Object and state information structure
 struct OBJTRACK_NODE {
-    uint64_t vkObj;                     // Object handle
-    VkDebugReportObjectTypeEXT objType; // Object type identifier
-    ObjectStatusFlags status;           // Object state
-    uint64_t parentObj;                 // Parent object
-    uint64_t belongsTo;                 // Object Scope -- owning device/instance
+    uint64_t handle;                        // Object handle (new)
+    VkDebugReportObjectTypeEXT object_type; // Object type identifier
+    ObjectStatusFlags status;               // Object state
+    uint64_t parent_object;                 // Parent object
 };
 
-// prototype for extension functions
-uint64_t objTrackGetObjectCount(VkDevice device);
-uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDebugReportObjectTypeEXT type);
+// Track Queue information
+struct OT_QUEUE_INFO {
+    uint32_t queue_node_index;
+    VkQueue queue;
+};
 
-// Func ptr typedefs
-typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
-typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDebugReportObjectTypeEXT);
+// Layer name string to be logged with validation messages.
+const char LayerName[] = "ObjectTracker";
 
+struct instance_extension_enables {
+    bool wsi_enabled;
+    bool xlib_enabled;
+    bool xcb_enabled;
+    bool wayland_enabled;
+    bool mir_enabled;
+    bool android_enabled;
+    bool win32_enabled;
+};
+
+typedef std::unordered_map<uint64_t, OBJTRACK_NODE *> object_map_type;
 struct layer_data {
     VkInstance instance;
+    VkPhysicalDevice physical_device;
+
+    uint64_t num_objects[VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT + 1];
+    uint64_t num_total_objects;
 
     debug_report_data *report_data;
-    // TODO: put instance data here
     std::vector<VkDebugReportCallbackEXT> logging_callback;
     bool wsi_enabled;
     bool objtrack_extensions_enabled;
+
     // The following are for keeping track of the temporary callbacks that can
     // be used in vkCreateInstance and vkDestroyInstance:
     uint32_t num_tmp_callbacks;
     VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
     VkDebugReportCallbackEXT *tmp_callbacks;
 
+    std::vector<VkQueueFamilyProperties> queue_family_properties;
+
+    // Vector of unordered_maps per object type to hold OBJTRACK_NODE info
+    std::vector<object_map_type> object_map;
+    // Special-case map for swapchain images
+    std::unordered_map<uint64_t, OBJTRACK_NODE *> swapchainImageMap;
+    // Map of queue information structures, one per queue
+    std::unordered_map<VkQueue, OT_QUEUE_INFO *> queue_info_map;
+
+    // Default constructor
     layer_data()
-        : report_data(nullptr), wsi_enabled(false), objtrack_extensions_enabled(false), num_tmp_callbacks(0),
-          tmp_dbg_create_infos(nullptr), tmp_callbacks(nullptr){};
+        : instance(nullptr), physical_device(nullptr), num_objects{}, num_total_objects(0), report_data(nullptr),
+          wsi_enabled(false), objtrack_extensions_enabled(false), num_tmp_callbacks(0), tmp_dbg_create_infos(nullptr),
+		  tmp_callbacks(nullptr), object_map{} {
+        object_map.resize(VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT + 1);
+    }
 };
 
-struct instExts {
-    bool wsi_enabled;
-};
 
-static std::unordered_map<void *, struct instExts> instanceExtMap;
+static std::unordered_map<void *, struct instance_extension_enables> instanceExtMap;
 static std::unordered_map<void *, layer_data *> layer_data_map;
-static device_table_map object_tracker_device_table_map;
-static instance_table_map object_tracker_instance_table_map;
-
-// We need additionally validate image usage using a separate map
-// of swapchain-created images
-static std::unordered_map<uint64_t, OBJTRACK_NODE *> swapchainImageMap;
-
-static long long unsigned int object_track_index = 0;
+static device_table_map ot_device_table_map;
+static instance_table_map ot_instance_table_map;
 static std::mutex global_lock;
+static uint64_t object_track_index = 0;
 
-#define NUM_OBJECT_TYPES (VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT + 1)
-
-static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
-static uint64_t numTotalObjs = 0;
-std::vector<VkQueueFamilyProperties> queue_family_properties;
-
-//
-// Internal Object Tracker Functions
-//
-
-static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkLayerDispatchTable *pDisp = get_dispatch_table(object_tracker_device_table_map, device);
-    PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
-    pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
-    pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
-    pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
-    pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
-    pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
-    my_device_data->wsi_enabled = false;
-    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
-            my_device_data->wsi_enabled = true;
-
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0)
-            my_device_data->objtrack_extensions_enabled = true;
-    }
-}
-
-static void createInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
-    uint32_t i;
-    VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(object_tracker_instance_table_map, instance);
-    PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
-
-    pDisp->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(instance, "vkDestroySurfaceKHR");
-    pDisp->GetPhysicalDeviceSurfaceSupportKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
-    pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
-    pDisp->GetPhysicalDeviceSurfaceFormatsKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
-    pDisp->GetPhysicalDeviceSurfacePresentModesKHR =
-        (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
-
-#if VK_USE_PLATFORM_WIN32_KHR
-    pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(instance, "vkCreateWin32SurfaceKHR");
-    pDisp->GetPhysicalDeviceWin32PresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
-#endif // VK_USE_PLATFORM_WIN32_KHR
-#ifdef VK_USE_PLATFORM_XCB_KHR
-    pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)gpa(instance, "vkCreateXcbSurfaceKHR");
-    pDisp->GetPhysicalDeviceXcbPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_XCB_KHR
-#ifdef VK_USE_PLATFORM_XLIB_KHR
-    pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)gpa(instance, "vkCreateXlibSurfaceKHR");
-    pDisp->GetPhysicalDeviceXlibPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_XLIB_KHR
-#ifdef VK_USE_PLATFORM_MIR_KHR
-    pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)gpa(instance, "vkCreateMirSurfaceKHR");
-    pDisp->GetPhysicalDeviceMirPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_MIR_KHR
-#ifdef VK_USE_PLATFORM_WAYLAND_KHR
-    pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)gpa(instance, "vkCreateWaylandSurfaceKHR");
-    pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
-#endif //  VK_USE_PLATFORM_WAYLAND_KHR
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
-    pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)gpa(instance, "vkCreateAndroidSurfaceKHR");
-#endif // VK_USE_PLATFORM_ANDROID_KHR
-
-    instanceExtMap[pDisp].wsi_enabled = false;
-    for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
-            instanceExtMap[pDisp].wsi_enabled = true;
-    }
-}
-
-// Indicate device or instance dispatch table type
-enum DispTableType {
-    DISP_TBL_TYPE_INSTANCE,
-    DISP_TBL_TYPE_DEVICE,
-};
-
-debug_report_data *mdd(const void *object) {
-    dispatch_key key = get_dispatch_key(object);
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    return my_data->report_data;
-}
-
-debug_report_data *mid(VkInstance object) {
-    dispatch_key key = get_dispatch_key(object);
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    return my_data->report_data;
-}
-
-// For each Queue's doubly linked-list of mem refs
-struct OT_MEM_INFO {
-    VkDeviceMemory mem;
-    OT_MEM_INFO *pNextMI;
-    OT_MEM_INFO *pPrevMI;
-};
-
-// Track Queue information
-struct OT_QUEUE_INFO {
-    OT_MEM_INFO *pMemRefList;
-    uint32_t queueNodeIndex;
-    VkQueue queue;
-    uint32_t refCount;
-};
-
-// Global map of structures, one per queue
-std::unordered_map<VkQueue, OT_QUEUE_INFO *> queue_info_map;
+// Array of object name strings for OBJECT_TYPE enum conversion
+static const char *object_name[VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT] = {
+    "Unknown",               // VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN
+    "Instance",              // VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT
+    "Physical Device",       // VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT
+    "Device",                // VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT
+    "Queue",                 // VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT
+    "Semaphore",             // VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT
+    "Command Buffer",        // VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT
+    "Fence",                 // VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT
+    "Device Memory",         // VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT
+    "Buffer",                // VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT
+    "Image",                 // VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT
+    "Event",                 // VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT
+    "Query Pool",            // VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT
+    "Buffer View",           // VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT
+    "Image View",            // VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT
+    "Shader Module",         // VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT
+    "Pipeline Cache",        // VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT
+    "Pipeline Layout",       // VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT
+    "Render Pass",           // VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT
+    "Pipeline",              // VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT
+    "Descriptor Set Layout", // VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT
+    "Sampler",               // VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT
+    "Descriptor Pool",       // VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT
+    "Descriptor Set",        // VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT
+    "Framebuffer",           // VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT
+    "Command Pool",          // VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT
+    "SurfaceKHR",            // VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT
+    "SwapchainKHR",          // VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT
+    "Debug Report" };        // VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT
 
 #include "vk_dispatch_table_helper.h"
 
-static void init_object_tracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
-
-    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_object_tracker");
-}
-
-//
-// Forward declarations
-//
-
-static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeEXT objType);
-static void create_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType);
-static void create_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
-static void create_device(VkPhysicalDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
-static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeEXT objType);
-static bool validate_image(VkQueue dispatchable_object, VkImage object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
-static bool validate_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType,
-                                  bool null_allowed);
-static bool validate_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType,
-                                bool null_allowed);
-static bool validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object, VkDebugReportObjectTypeEXT objType,
-                                         bool null_allowed);
-static bool validate_descriptor_set_layout(VkDevice dispatchable_object, VkDescriptorSetLayout object,
-                                               VkDebugReportObjectTypeEXT objType, bool null_allowed);
-static bool validate_command_pool(VkDevice dispatchable_object, VkCommandPool object, VkDebugReportObjectTypeEXT objType,
-                                      bool null_allowed);
-static bool validate_buffer(VkQueue dispatchable_object, VkBuffer object, VkDebugReportObjectTypeEXT objType,
-                                bool null_allowed);
-static void create_pipeline(VkDevice dispatchable_object, VkPipeline vkObj, VkDebugReportObjectTypeEXT objType);
-static bool validate_pipeline_cache(VkDevice dispatchable_object, VkPipelineCache object, VkDebugReportObjectTypeEXT objType,
-                                        bool null_allowed);
-static bool validate_render_pass(VkDevice dispatchable_object, VkRenderPass object, VkDebugReportObjectTypeEXT objType,
-                                     bool null_allowed);
-static bool validate_shader_module(VkDevice dispatchable_object, VkShaderModule object, VkDebugReportObjectTypeEXT objType,
-                                       bool null_allowed);
-static bool validate_pipeline_layout(VkDevice dispatchable_object, VkPipelineLayout object, VkDebugReportObjectTypeEXT objType,
-                                         bool null_allowed);
-static bool validate_pipeline(VkDevice dispatchable_object, VkPipeline object, VkDebugReportObjectTypeEXT objType,
-                                  bool null_allowed);
-static void destroy_command_pool(VkDevice dispatchable_object, VkCommandPool object);
-static void destroy_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
-static void destroy_descriptor_set(VkDevice dispatchable_object, VkDescriptorSet object);
-static void destroy_device_memory(VkDevice dispatchable_object, VkDeviceMemory object);
-static void destroy_swapchain_khr(VkDevice dispatchable_object, VkSwapchainKHR object);
-static bool set_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeEXT objType,
-                                         ObjectStatusFlags status_flag);
-static bool reset_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeEXT objType,
-                                           ObjectStatusFlags status_flag);
-static void destroy_queue(VkQueue dispatchable_object, VkQueue object);
-
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkPhysicalDeviceMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkDeviceMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkImageMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkQueueMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkDescriptorSetMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkBufferMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkFenceMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkSemaphoreMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkCommandPoolMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkCommandBufferMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkSwapchainKHRMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkSurfaceKHRMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkQueueMap;
-
-// Convert an object type enum to an object type array index
-static uint32_t objTypeToIndex(uint32_t objType) {
-    uint32_t index = objType;
-    return index;
-}
-
-// Add new queue to head of global queue list
-static void addQueueInfo(uint32_t queueNodeIndex, VkQueue queue) {
-    auto queueItem = queue_info_map.find(queue);
-    if (queueItem == queue_info_map.end()) {
-        OT_QUEUE_INFO *p_queue_info = new OT_QUEUE_INFO;
-        if (p_queue_info != NULL) {
-            memset(p_queue_info, 0, sizeof(OT_QUEUE_INFO));
-            p_queue_info->queue = queue;
-            p_queue_info->queueNodeIndex = queueNodeIndex;
-            queue_info_map[queue] = p_queue_info;
-        } else {
-            log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
-                    reinterpret_cast<uint64_t>(queue), __LINE__, OBJTRACK_INTERNAL_ERROR, "OBJTRACK",
-                    "ERROR:  VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
-        }
-    }
-}
-
-// Destroy memRef lists and free all memory
-static void destroyQueueMemRefLists() {
-    for (auto queue_item : queue_info_map) {
-        OT_MEM_INFO *p_mem_info = queue_item.second->pMemRefList;
-        while (p_mem_info != NULL) {
-            OT_MEM_INFO *p_del_mem_info = p_mem_info;
-            p_mem_info = p_mem_info->pNextMI;
-            delete p_del_mem_info;
-        }
-        delete queue_item.second;
-    }
-    queue_info_map.clear();
-
-    // Destroy the items in the queue map
-    auto queue = VkQueueMap.begin();
-    while (queue != VkQueueMap.end()) {
-        uint32_t obj_index = objTypeToIndex(queue->second->objType);
-        assert(numTotalObjs > 0);
-        numTotalObjs--;
-        assert(numObjs[obj_index] > 0);
-        numObjs[obj_index]--;
-        log_msg(mdd(reinterpret_cast<VkQueue>(queue->second->vkObj)), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, queue->second->objType,
-                queue->second->vkObj, __LINE__, OBJTRACK_NONE, "OBJTRACK",
-                "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
-                string_VkDebugReportObjectTypeEXT(queue->second->objType), queue->second->vkObj, numTotalObjs, numObjs[obj_index],
-                string_VkDebugReportObjectTypeEXT(queue->second->objType));
-        delete queue->second;
-        queue = VkQueueMap.erase(queue);
-    }
-}
-
-// Check Queue type flags for selected queue operations
-static void validateQueueFlags(VkQueue queue, const char *function) {
-
-    auto queue_item = queue_info_map.find(queue);
-    if (queue_item != queue_info_map.end()) {
-        OT_QUEUE_INFO *pQueueInfo = queue_item->second;
-        if (pQueueInfo != NULL) {
-            if ((queue_family_properties[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
-                log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
-                        reinterpret_cast<uint64_t>(queue), __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
-                        "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
-            }
-        }
-    }
-}
-
-static void create_physical_device(VkInstance instance, VkPhysicalDevice vkObj, VkDebugReportObjectTypeEXT objType) {
-    log_msg(mdd(instance), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__,
-            OBJTRACK_NONE, "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
-
-    uint64_t physical_device_handle = reinterpret_cast<uint64_t>(vkObj);
-    auto pd_item = VkPhysicalDeviceMap.find(physical_device_handle);
-    if (pd_item == VkPhysicalDeviceMap.end()) {
-        OBJTRACK_NODE *p_new_obj_node = new OBJTRACK_NODE;
-        p_new_obj_node->objType = objType;
-        p_new_obj_node->belongsTo = reinterpret_cast<uint64_t>(instance);
-        p_new_obj_node->status = OBJSTATUS_NONE;
-        p_new_obj_node->vkObj = physical_device_handle;
-        VkPhysicalDeviceMap[physical_device_handle] = p_new_obj_node;
-        uint32_t objIndex = objTypeToIndex(objType);
-        numObjs[objIndex]++;
-        numTotalObjs++;
-    }
-}
-
-static void create_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR vkObj, VkDebugReportObjectTypeEXT objType) {
-    // TODO: Add tracking of surface objects
-    log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), (uint64_t)(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->objType = objType;
-    pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->vkObj = (uint64_t)(vkObj);
-    VkSurfaceKHRMap[(uint64_t)vkObj] = pNewObjNode;
-    uint32_t objIndex = objTypeToIndex(objType);
-    numObjs[objIndex]++;
-    numTotalObjs++;
-}
-
-static void destroy_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR object) {
-    uint64_t object_handle = (uint64_t)(object);
-    if (VkSurfaceKHRMap.find(object_handle) != VkSurfaceKHRMap.end()) {
-        OBJTRACK_NODE *pNode = VkSurfaceKHRMap[(uint64_t)object];
-        uint32_t objIndex = objTypeToIndex(pNode->objType);
-        assert(numTotalObjs > 0);
-        numTotalObjs--;
-        assert(numObjs[objIndex] > 0);
-        numObjs[objIndex]--;
-        log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__,
-                OBJTRACK_NONE, "OBJTRACK",
-                "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (0x%" PRIx64 " total objs remain & 0x%" PRIx64 " %s objs).",
-                string_VkDebugReportObjectTypeEXT(pNode->objType), (uint64_t)(object), numTotalObjs, numObjs[objIndex],
-                string_VkDebugReportObjectTypeEXT(pNode->objType));
-        delete pNode;
-        VkSurfaceKHRMap.erase(object_handle);
-    } else {
-        log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__,
-                OBJTRACK_NONE, "OBJTRACK",
-                "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", object_handle);
-    }
-}
-
-static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer vkObj,
-                                 VkDebugReportObjectTypeEXT objType, VkCommandBufferLevel level) {
-    log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->objType = objType;
-    pNewObjNode->belongsTo = (uint64_t)device;
-    pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
-    pNewObjNode->parentObj = (uint64_t)commandPool;
-    if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
-        pNewObjNode->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
-    } else {
-        pNewObjNode->status = OBJSTATUS_NONE;
-    }
-    VkCommandBufferMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
-    uint32_t objIndex = objTypeToIndex(objType);
-    numObjs[objIndex]++;
-    numTotalObjs++;
-}
-
-static bool validate_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer) {
-    bool skipCall = false;
-    uint64_t object_handle = reinterpret_cast<uint64_t>(commandBuffer);
-    if (VkCommandBufferMap.find(object_handle) != VkCommandBufferMap.end()) {
-        OBJTRACK_NODE *pNode = VkCommandBufferMap[(uint64_t)commandBuffer];
-
-        if (pNode->parentObj != (uint64_t)(commandPool)) {
-            skipCall |= log_msg(
-                mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_COMMAND_POOL_MISMATCH,
-                "OBJTRACK", "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64
-                            " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
-                reinterpret_cast<uint64_t>(commandBuffer), pNode->parentObj, reinterpret_cast<uint64_t &>(commandPool));
-        }
-    } else {
-        skipCall |= log_msg(
-            mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", object_handle);
-    }
-    return skipCall;
-}
-
-static bool free_command_buffer(VkDevice device, VkCommandBuffer commandBuffer) {
-    bool skipCall = false;
-    auto cbItem = VkCommandBufferMap.find(reinterpret_cast<uint64_t>(commandBuffer));
-    if (cbItem != VkCommandBufferMap.end()) {
-        OBJTRACK_NODE *pNode = cbItem->second;
-        uint32_t objIndex = objTypeToIndex(pNode->objType);
-        assert(numTotalObjs > 0);
-        numTotalObjs--;
-        assert(numObjs[objIndex] > 0);
-        numObjs[objIndex]--;
-        skipCall |= log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType,
-                            reinterpret_cast<uint64_t>(commandBuffer), __LINE__, OBJTRACK_NONE, "OBJTRACK",
-                            "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
-                            string_VkDebugReportObjectTypeEXT(pNode->objType), reinterpret_cast<uint64_t>(commandBuffer),
-                            numTotalObjs, numObjs[objIndex], string_VkDebugReportObjectTypeEXT(pNode->objType));
-        delete pNode;
-        VkCommandBufferMap.erase(cbItem);
-    }
-    return skipCall;
-}
-
-static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet vkObj,
-                                 VkDebugReportObjectTypeEXT objType) {
-    log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",
-            "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++, string_VkDebugReportObjectTypeEXT(objType),
-            (uint64_t)(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->objType = objType;
-    pNewObjNode->belongsTo = (uint64_t)device;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->vkObj = (uint64_t)(vkObj);
-    pNewObjNode->parentObj = (uint64_t)descriptorPool;
-    VkDescriptorSetMap[(uint64_t)vkObj] = pNewObjNode;
-    uint32_t objIndex = objTypeToIndex(objType);
-    numObjs[objIndex]++;
-    numTotalObjs++;
-}
-
-static bool validate_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet descriptorSet) {
-    bool skipCall = false;
-    uint64_t object_handle = reinterpret_cast<uint64_t &>(descriptorSet);
-    auto dsItem = VkDescriptorSetMap.find(object_handle);
-    if (dsItem != VkDescriptorSetMap.end()) {
-        OBJTRACK_NODE *pNode = dsItem->second;
-
-        if (pNode->parentObj != reinterpret_cast<uint64_t &>(descriptorPool)) {
-            skipCall |= log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, object_handle, __LINE__,
-                                OBJTRACK_DESCRIPTOR_POOL_MISMATCH, "OBJTRACK",
-                                "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64
-                                " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
-                                reinterpret_cast<uint64_t &>(descriptorSet), pNode->parentObj,
-                                reinterpret_cast<uint64_t &>(descriptorPool));
-        }
-    } else {
-        skipCall |= log_msg(
-            mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", object_handle);
-    }
-    return skipCall;
-}
-
-static bool free_descriptor_set(VkDevice device, VkDescriptorSet descriptorSet) {
-    bool skipCall = false;
-    auto dsItem = VkDescriptorSetMap.find(reinterpret_cast<uint64_t &>(descriptorSet));
-    if (dsItem != VkDescriptorSetMap.end()) {
-        OBJTRACK_NODE *pNode = dsItem->second;
-        uint32_t objIndex = objTypeToIndex(pNode->objType);
-        assert(numTotalObjs > 0);
-        numTotalObjs--;
-        assert(numObjs[objIndex] > 0);
-        numObjs[objIndex]--;
-        skipCall |= log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType,
-                            reinterpret_cast<uint64_t &>(descriptorSet), __LINE__, OBJTRACK_NONE, "OBJTRACK",
-                            "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
-                            string_VkDebugReportObjectTypeEXT(pNode->objType), reinterpret_cast<uint64_t &>(descriptorSet),
-                            numTotalObjs, numObjs[objIndex], string_VkDebugReportObjectTypeEXT(pNode->objType));
-        delete pNode;
-        VkDescriptorSetMap.erase(dsItem);
-    }
-    return skipCall;
-}
-
-static void create_queue(VkDevice device, VkQueue vkObj, VkDebugReportObjectTypeEXT objType) {
-
-    log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__,
-            OBJTRACK_NONE, "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
-
-    OBJTRACK_NODE *p_obj_node = NULL;
-    auto queue_item = VkQueueMap.find(reinterpret_cast<uint64_t>(vkObj));
-    if (queue_item == VkQueueMap.end()) {
-        p_obj_node = new OBJTRACK_NODE;
-        VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = p_obj_node;
-        uint32_t objIndex = objTypeToIndex(objType);
-        numObjs[objIndex]++;
-        numTotalObjs++;
-    } else {
-        p_obj_node = queue_item->second;
-    }
-    p_obj_node->objType = objType;
-    p_obj_node->belongsTo = reinterpret_cast<uint64_t>(device);
-    p_obj_node->status = OBJSTATUS_NONE;
-    p_obj_node->vkObj = reinterpret_cast<uint64_t>(vkObj);
-}
-
-static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain) {
-    log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)vkObj,
-            __LINE__, OBJTRACK_NONE, "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            "SwapchainImage", (uint64_t)(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
-    pNewObjNode->objType = VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->vkObj = (uint64_t)vkObj;
-    pNewObjNode->parentObj = (uint64_t)swapchain;
-    swapchainImageMap[(uint64_t)(vkObj)] = pNewObjNode;
-}
-
-static void create_device(VkInstance dispatchable_object, VkDevice vkObj, VkDebugReportObjectTypeEXT objType) {
-    log_msg(mid(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), (uint64_t)(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
-    pNewObjNode->objType = objType;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->vkObj = (uint64_t)(vkObj);
-    VkDeviceMap[(uint64_t)vkObj] = pNewObjNode;
-    uint32_t objIndex = objTypeToIndex(objType);
-    numObjs[objIndex]++;
-    numTotalObjs++;
-}
-
-//
-// Non-auto-generated API functions called by generated code
-//
-VkResult explicit_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
-                                 VkInstance *pInstance) {
-    VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
-
-    assert(chain_info->u.pLayerInfo);
-    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
-    if (fpCreateInstance == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    // Advance the link info for the next element on the chain
-    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
-
-    VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
-    if (result != VK_SUCCESS) {
-        return result;
-    }
-
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
-    my_data->instance = *pInstance;
-    initInstanceTable(*pInstance, fpGetInstanceProcAddr, object_tracker_instance_table_map);
-    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, *pInstance);
-
-    // Look for one or more debug report create info structures, and copy the
-    // callback(s) for each one found (for use by vkDestroyInstance)
-    layer_copy_tmp_callbacks(pCreateInfo->pNext, &my_data->num_tmp_callbacks, &my_data->tmp_dbg_create_infos,
-                             &my_data->tmp_callbacks);
-
-    my_data->report_data = debug_report_create_instance(pInstanceTable, *pInstance, pCreateInfo->enabledExtensionCount,
-                                                        pCreateInfo->ppEnabledExtensionNames);
-
-    init_object_tracker(my_data, pAllocator);
-    createInstanceRegisterExtensions(pCreateInfo, *pInstance);
-
-    create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
-
-    return result;
-}
-
-void explicit_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice gpu, uint32_t *pCount, VkQueueFamilyProperties *pProperties) {
-    get_dispatch_table(object_tracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
-
-    std::lock_guard<std::mutex> lock(global_lock);
-    if (pProperties != NULL) {
-        for (uint32_t i = 0; i < *pCount; i++) {
-            queue_family_properties.emplace_back(pProperties[i]);
-        }
-    }
-}
-
-VkResult explicit_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
-                               VkDevice *pDevice) {
-    std::lock_guard<std::mutex> lock(global_lock);
-    layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
-    VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
-
-    assert(chain_info->u.pLayerInfo);
-    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
-    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
-    if (fpCreateDevice == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    // Advance the link info for the next element on the chain
-    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
-
-    VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
-    if (result != VK_SUCCESS) {
-        return result;
-    }
-
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
-    my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
-
-    initDeviceTable(*pDevice, fpGetDeviceProcAddr, object_tracker_device_table_map);
-
-    createDeviceRegisterExtensions(pCreateInfo, *pDevice);
-
-    if (VkPhysicalDeviceMap.find((uint64_t)gpu) != VkPhysicalDeviceMap.end()) {
-        OBJTRACK_NODE *pNewObjNode = VkPhysicalDeviceMap[(uint64_t)gpu];
-        create_device((VkInstance)pNewObjNode->belongsTo, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
-    }
-
-    return result;
-}
-
-VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
-                                           VkPhysicalDevice *pPhysicalDevices) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_instance(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
-    lock.unlock();
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = get_dispatch_table(object_tracker_instance_table_map, instance)
-                          ->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
-    lock.lock();
-    if (result == VK_SUCCESS) {
-        if (pPhysicalDevices) {
-            for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
-                create_physical_device(instance, pPhysicalDevices[i], VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT);
-            }
-        }
-    }
-    lock.unlock();
-    return result;
-}
-
-void explicit_GetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue *pQueue) {
-    std::unique_lock<std::mutex> lock(global_lock);
-    validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-
-    get_dispatch_table(object_tracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
-
-    lock.lock();
-
-    create_queue(device, *pQueue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT);
-    addQueueInfo(queueNodeIndex, *pQueue);
-}
-
-VkResult explicit_MapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags,
-                            void **ppData) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-    if (skipCall == VK_TRUE)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-
-    VkResult result =
-        get_dispatch_table(object_tracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
-
-    return result;
-}
-
-void explicit_UnmapMemory(VkDevice device, VkDeviceMemory mem) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-    if (skipCall == VK_TRUE)
-        return;
-
-    get_dispatch_table(object_tracker_device_table_map, device)->UnmapMemory(device, mem);
-}
-
-VkResult explicit_QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence) {
-    std::unique_lock<std::mutex> lock(global_lock);
-    validateQueueFlags(queue, "QueueBindSparse");
-
-    for (uint32_t i = 0; i < bindInfoCount; i++) {
-        for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
-            validate_buffer(queue, pBindInfo[i].pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
-            validate_image(queue, pBindInfo[i].pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-        for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
-            validate_image(queue, pBindInfo[i].pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-    }
-    lock.unlock();
-
-    VkResult result =
-        get_dispatch_table(object_tracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
-    return result;
-}
-
-VkResult explicit_AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
-                                         VkCommandBuffer *pCommandBuffers) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skipCall |= validate_command_pool(device, pAllocateInfo->commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
-    lock.unlock();
-
-    if (skipCall) {
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    }
-
-    VkResult result =
-        get_dispatch_table(object_tracker_device_table_map, device)->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
-
-    lock.lock();
-    for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
-        alloc_command_buffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                             pAllocateInfo->level);
-    }
-    lock.unlock();
-
-    return result;
-}
-
-VkResult explicit_AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
-                                         VkDescriptorSet *pDescriptorSets) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skipCall |=
-        validate_descriptor_pool(device, pAllocateInfo->descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
-    for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
-        skipCall |= validate_descriptor_set_layout(device, pAllocateInfo->pSetLayouts[i],
-                                                   VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
-    }
-    lock.unlock();
-    if (skipCall) {
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    }
-
-    VkResult result =
-        get_dispatch_table(object_tracker_device_table_map, device)->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
-
-    if (VK_SUCCESS == result) {
-        lock.lock();
-        for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
-            alloc_descriptor_set(device, pAllocateInfo->descriptorPool, pDescriptorSets[i],
-                                 VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
-        }
-        lock.unlock();
-    }
-
-    return result;
-}
-
-void explicit_FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
-                                 const VkCommandBuffer *pCommandBuffers) {
-    bool skipCall = false;
-    std::unique_lock<std::mutex> lock(global_lock);
-    validate_command_pool(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
-    validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    for (uint32_t i = 0; i < commandBufferCount; i++) {
-        skipCall |= validate_command_buffer(device, commandPool, pCommandBuffers[i]);
-    }
-
-    lock.unlock();
-    if (!skipCall) {
-        get_dispatch_table(object_tracker_device_table_map, device)
-            ->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
-    }
-
-    lock.lock();
-    for (uint32_t i = 0; i < commandBufferCount; i++) {
-        free_command_buffer(device, pCommandBuffers[i]);
-    }
-}
-
-void explicit_DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
-    std::unique_lock<std::mutex> lock(global_lock);
-    // A swapchain's images are implicitly deleted when the swapchain is deleted.
-    // Remove this swapchain's images from our map of such images.
-    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = swapchainImageMap.begin();
-    while (itr != swapchainImageMap.end()) {
-        OBJTRACK_NODE *pNode = (*itr).second;
-        if (pNode->parentObj == reinterpret_cast<uint64_t &>(swapchain)) {
-            delete pNode;
-            swapchainImageMap.erase(itr++);
-        } else {
-            ++itr;
-        }
-    }
-    destroy_swapchain_khr(device, swapchain);
-    lock.unlock();
-
-    get_dispatch_table(object_tracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
-}
-
-void explicit_FreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
-    std::unique_lock<std::mutex> lock(global_lock);
-    validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-
-    get_dispatch_table(object_tracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
-
-    lock.lock();
-    destroy_device_memory(device, mem);
-}
-
-VkResult explicit_FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count,
-                                     const VkDescriptorSet *pDescriptorSets) {
-    bool skipCall = false;
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_descriptor_pool(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    for (uint32_t i = 0; i < count; i++) {
-        skipCall |= validate_descriptor_set(device, descriptorPool, pDescriptorSets[i]);
-    }
-
-    lock.unlock();
-    if (!skipCall) {
-        result = get_dispatch_table(object_tracker_device_table_map, device)
-                     ->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
-    }
-
-    lock.lock();
-    for (uint32_t i = 0; i < count; i++) {
-        free_descriptor_set(device, pDescriptorSets[i]);
-    }
-    return result;
-}
-
-void explicit_DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skipCall |= validate_descriptor_pool(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
-    lock.unlock();
-    if (skipCall) {
-        return;
-    }
-    // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
-    // Remove this pool's descriptor sets from our descriptorSet map.
-    lock.lock();
-    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = VkDescriptorSetMap.begin();
-    while (itr != VkDescriptorSetMap.end()) {
-        OBJTRACK_NODE *pNode = (*itr).second;
-        auto del_itr = itr++;
-        if (pNode->parentObj == (uint64_t)(descriptorPool)) {
-            destroy_descriptor_set(device, (VkDescriptorSet)((*del_itr).first));
-        }
-    }
-    destroy_descriptor_pool(device, descriptorPool);
-    lock.unlock();
-    get_dispatch_table(object_tracker_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
-}
-
-void explicit_DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skipCall |= validate_command_pool(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
-    lock.unlock();
-    if (skipCall) {
-        return;
-    }
-    lock.lock();
-    // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
-    // Remove this pool's cmdBuffers from our cmd buffer map.
-    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = VkCommandBufferMap.begin();
-    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator del_itr;
-    while (itr != VkCommandBufferMap.end()) {
-        OBJTRACK_NODE *pNode = (*itr).second;
-        del_itr = itr++;
-        if (pNode->parentObj == (uint64_t)(commandPool)) {
-            skipCall |= validate_command_buffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
-            free_command_buffer(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
-        }
-    }
-    destroy_command_pool(device, commandPool);
-    lock.unlock();
-    get_dispatch_table(object_tracker_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
-}
-
-VkResult explicit_GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pCount, VkImage *pSwapchainImages) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-
-    VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
-                          ->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
-
-    if (pSwapchainImages != NULL) {
-        lock.lock();
-        for (uint32_t i = 0; i < *pCount; i++) {
-            create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
-        }
-        lock.unlock();
-    }
-    return result;
-}
-
-// TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
-VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
-                                          const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
-                                          VkPipeline *pPipelines) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    if (pCreateInfos) {
-        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
-            if (pCreateInfos[idx0].basePipelineHandle) {
-                skipCall |= validate_pipeline(device, pCreateInfos[idx0].basePipelineHandle,
-                                              VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
-            }
-            if (pCreateInfos[idx0].layout) {
-                skipCall |= validate_pipeline_layout(device, pCreateInfos[idx0].layout,
-                                                     VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
-            }
-            if (pCreateInfos[idx0].pStages) {
-                for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
-                    if (pCreateInfos[idx0].pStages[idx1].module) {
-                        skipCall |= validate_shader_module(device, pCreateInfos[idx0].pStages[idx1].module,
-                                                           VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
-                    }
-                }
-            }
-            if (pCreateInfos[idx0].renderPass) {
-                skipCall |=
-                    validate_render_pass(device, pCreateInfos[idx0].renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
-            }
-        }
-    }
-    if (pipelineCache) {
-        skipCall |= validate_pipeline_cache(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
-    }
-    lock.unlock();
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
-                          ->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
-    lock.lock();
-    if (result == VK_SUCCESS) {
-        for (uint32_t idx2 = 0; idx2 < createInfoCount; ++idx2) {
-            create_pipeline(device, pPipelines[idx2], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
-        }
-    }
-    lock.unlock();
-    return result;
-}
-
-// TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
-VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
-                                         const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
-                                         VkPipeline *pPipelines) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    if (pCreateInfos) {
-        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
-            if (pCreateInfos[idx0].basePipelineHandle) {
-                skipCall |= validate_pipeline(device, pCreateInfos[idx0].basePipelineHandle,
-                                              VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
-            }
-            if (pCreateInfos[idx0].layout) {
-                skipCall |= validate_pipeline_layout(device, pCreateInfos[idx0].layout,
-                                                     VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
-            }
-            if (pCreateInfos[idx0].stage.module) {
-                skipCall |= validate_shader_module(device, pCreateInfos[idx0].stage.module,
-                                                   VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
-            }
-        }
-    }
-    if (pipelineCache) {
-        skipCall |= validate_pipeline_cache(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
-    }
-    lock.unlock();
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
-                          ->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
-    lock.lock();
-    if (result == VK_SUCCESS) {
-        for (uint32_t idx1 = 0; idx1 < createInfoCount; ++idx1) {
-            create_pipeline(device, pPipelines[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
-        }
-    }
-    lock.unlock();
-    return result;
-}
-
 } // namespace object_tracker
diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp
index e0e29c6..e19e07c 100644
--- a/layers/parameter_validation.cpp
+++ b/layers/parameter_validation.cpp
@@ -67,10 +67,18 @@
     // Device Data
     // Map for queue family index to queue count
     std::unordered_map<uint32_t, uint32_t> queueFamilyIndexMap;
+    VkPhysicalDeviceLimits device_limits;
+    VkPhysicalDeviceFeatures physical_device_features;
+    VkPhysicalDevice physical_device;
 
-    layer_data() : report_data(nullptr), num_tmp_callbacks(0), tmp_dbg_create_infos(nullptr), tmp_callbacks(nullptr){};
+    bool wsi_enabled;
+
+    layer_data()
+        : report_data(nullptr), num_tmp_callbacks(0), tmp_dbg_create_infos(nullptr), tmp_callbacks(nullptr), device_limits{},
+          physical_device_features{}, physical_device{}, wsi_enabled(false){};
 };
 
+static std::unordered_map<void *, struct instance_extension_enables> instance_extension_map;
 static std::unordered_map<void *, layer_data *> layer_data_map;
 static device_table_map pc_device_table_map;
 static instance_table_map pc_instance_table_map;
@@ -103,22 +111,22 @@
     layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_parameter_validation");
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
-                             const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
+                                                            const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+                                                            const VkAllocationCallbacks *pAllocator,
+                                                            VkDebugReportCallbackEXT *pMsgCallback) {
     VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance);
     VkResult result = pTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
 
     if (result == VK_SUCCESS) {
         layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-        result = layer_create_msg_callback(data->report_data, pCreateInfo, pAllocator, pMsgCallback);
+        result = layer_create_msg_callback(data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
     }
 
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance,
-                                                         VkDebugReportCallbackEXT msgCallback,
+VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
                                                          const VkAllocationCallbacks *pAllocator) {
     VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance);
     pTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
@@ -127,9 +135,9 @@
     layer_destroy_msg_callback(data->report_data, msgCallback, pAllocator);
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
-                      size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+                                                 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+                                                 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
     VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance);
     pTable->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
 }
@@ -1222,22 +1230,22 @@
     assert(stringName != nullptr);
     assert(validateString != nullptr);
 
-    bool skipCall = false;
+    bool skip_call = false;
 
     VkStringErrorFlags result = vk_string_validate(MaxParamCheckerStringLength, validateString);
 
     if (result == VK_STRING_ERROR_NONE) {
-        return skipCall;
+        return skip_call;
     } else if (result & VK_STRING_ERROR_LENGTH) {
-        skipCall =
+        skip_call =
             log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, INVALID_USAGE,
-                    "PARAMCHECK", "%s: string %s exceeds max length %d", apiName, stringName, MaxParamCheckerStringLength);
+                    LayerName, "%s: string %s exceeds max length %d", apiName, stringName, MaxParamCheckerStringLength);
     } else if (result & VK_STRING_ERROR_BAD_DATA) {
-        skipCall =
+        skip_call =
             log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, INVALID_USAGE,
-                    "PARAMCHECK", "%s: string %s contains invalid characters or is badly formed", apiName, stringName);
+                    LayerName, "%s: string %s contains invalid characters or is badly formed", apiName, stringName);
     }
-    return skipCall;
+    return skip_call;
 }
 
 static bool validate_queue_family_index(layer_data *device_data, const char *function_name, const char *parameter_name,
@@ -1247,14 +1255,14 @@
     bool skip_call = false;
 
     if (index == VK_QUEUE_FAMILY_IGNORED) {
-        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
-                             "PARAMCHECK", "%s: %s cannot be VK_QUEUE_FAMILY_IGNORED.", function_name, parameter_name);
+        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName,
+                             "%s: %s cannot be VK_QUEUE_FAMILY_IGNORED.", function_name, parameter_name);
     } else {
         const auto &queue_data = device_data->queueFamilyIndexMap.find(index);
         if (queue_data == device_data->queueFamilyIndexMap.end()) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
-                                 "PARAMCHECK", "%s: %s (%d) must be one of the indices specified when the device was created, via "
-                                               "the VkDeviceQueueCreateInfo structure.",
+                                 LayerName, "%s: %s (%d) must be one of the indices specified when the device was created, via "
+                                            "the VkDeviceQueueCreateInfo structure.",
                                  function_name, parameter_name, index);
             return false;
         }
@@ -1272,15 +1280,14 @@
     if (indices != nullptr) {
         for (uint32_t i = 0; i < count; i++) {
             if (indices[i] == VK_QUEUE_FAMILY_IGNORED) {
-                skip_call |=
-                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, "PARAMCHECK",
-                            "%s: %s[%d] cannot be VK_QUEUE_FAMILY_IGNORED.", function_name, parameter_name, i);
+                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
+                                     LayerName, "%s: %s[%d] cannot be VK_QUEUE_FAMILY_IGNORED.", function_name, parameter_name, i);
             } else {
                 const auto &queue_data = device_data->queueFamilyIndexMap.find(indices[i]);
                 if (queue_data == device_data->queueFamilyIndexMap.end()) {
                     skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
-                                         "PARAMCHECK", "%s: %s[%d] (%d) must be one of the indices specified when the device was "
-                                                       "created, via the VkDeviceQueueCreateInfo structure.",
+                                         LayerName, "%s: %s[%d] (%d) must be one of the indices specified when the device was "
+                                                    "created, via the VkDeviceQueueCreateInfo structure.",
                                          function_name, parameter_name, i, indices[i]);
                     return false;
                 }
@@ -1291,8 +1298,8 @@
     return skip_call;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
+                                              VkInstance *pInstance) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
 
     VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
@@ -1368,7 +1375,7 @@
 VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
     // Grab the key before the instance is destroyed.
     dispatch_key key = get_dispatch_key(instance);
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(key, layer_data_map);
     assert(my_data != NULL);
 
@@ -1381,7 +1388,7 @@
         }
     }
 
-    skipCall |= parameter_validation_vkDestroyInstance(my_data->report_data, pAllocator);
+    skip_call |= parameter_validation_vkDestroyInstance(my_data->report_data, pAllocator);
 
     // Disable and cleanup the temporary callback(s):
     if (callback_setup) {
@@ -1392,7 +1399,7 @@
         my_data->num_tmp_callbacks = 0;
     }
 
-    if (!skipCall) {
+    if (!skip_call) {
         VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance);
         pTable->DestroyInstance(instance, pAllocator);
 
@@ -1411,65 +1418,71 @@
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) {
+VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
+                                                        VkPhysicalDevice *pPhysicalDevices) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkEnumeratePhysicalDevices(my_data->report_data, pPhysicalDeviceCount, pPhysicalDevices);
+    skip_call |= parameter_validation_vkEnumeratePhysicalDevices(my_data->report_data, pPhysicalDeviceCount, pPhysicalDevices);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_instance_table_map, instance)
                      ->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
 
         validate_result(my_data->report_data, "vkEnumeratePhysicalDevices", result);
+        if ((result == VK_SUCCESS) && (NULL != pPhysicalDevices)) {
+            for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
+                layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map);
+                // Save the supported features for each physical device
+                VkLayerInstanceDispatchTable *disp_table = get_dispatch_table(pc_instance_table_map, pPhysicalDevices[i]);
+                disp_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i], &(phy_dev_data->physical_device_features));
+            }
+        }
     }
-
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetPhysicalDeviceFeatures(my_data->report_data, pFeatures);
+    skip_call |= parameter_validation_vkGetPhysicalDeviceFeatures(my_data->report_data, pFeatures);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_instance_table_map, physicalDevice)->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+                                                             VkFormatProperties *pFormatProperties) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetPhysicalDeviceFormatProperties(my_data->report_data, format, pFormatProperties);
+    skip_call |= parameter_validation_vkGetPhysicalDeviceFormatProperties(my_data->report_data, format, pFormatProperties);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_instance_table_map, physicalDevice)
             ->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
-                                       VkImageUsageFlags usage, VkImageCreateFlags flags,
-                                       VkImageFormatProperties *pImageFormatProperties) {
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+                                                                      VkImageType type, VkImageTiling tiling,
+                                                                      VkImageUsageFlags usage, VkImageCreateFlags flags,
+                                                                      VkImageFormatProperties *pImageFormatProperties) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetPhysicalDeviceImageFormatProperties(my_data->report_data, format, type, tiling, usage, flags,
-                                                                     pImageFormatProperties);
+    skip_call |= parameter_validation_vkGetPhysicalDeviceImageFormatProperties(my_data->report_data, format, type, tiling, usage,
+                                                                               flags, pImageFormatProperties);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_instance_table_map, physicalDevice)
                      ->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags,
                                                               pImageFormatProperties);
@@ -1480,44 +1493,43 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetPhysicalDeviceProperties(my_data->report_data, pProperties);
+    skip_call |= parameter_validation_vkGetPhysicalDeviceProperties(my_data->report_data, pProperties);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_instance_table_map, physicalDevice)->GetPhysicalDeviceProperties(physicalDevice, pProperties);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount,
-                                       VkQueueFamilyProperties *pQueueFamilyProperties) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
+                                                                  uint32_t *pQueueFamilyPropertyCount,
+                                                                  VkQueueFamilyProperties *pQueueFamilyProperties) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetPhysicalDeviceQueueFamilyProperties(my_data->report_data, pQueueFamilyPropertyCount,
-                                                                     pQueueFamilyProperties);
+    skip_call |= parameter_validation_vkGetPhysicalDeviceQueueFamilyProperties(my_data->report_data, pQueueFamilyPropertyCount,
+                                                                               pQueueFamilyProperties);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_instance_table_map, physicalDevice)
             ->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
+                                                             VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetPhysicalDeviceMemoryProperties(my_data->report_data, pMemoryProperties);
+    skip_call |= parameter_validation_vkGetPhysicalDeviceMemoryProperties(my_data->report_data, pMemoryProperties);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_instance_table_map, physicalDevice)
             ->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
     }
@@ -1531,7 +1543,7 @@
         for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
             if (set.count(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex)) {
                 log_msg(mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                        INVALID_USAGE, "PARAMCHECK",
+                        INVALID_USAGE, LayerName,
                         "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueFamilyIndex, is not unique within this "
                         "structure.",
                         i);
@@ -1544,7 +1556,7 @@
                     if ((pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j] < 0.f) ||
                         (pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j] > 1.f)) {
                         log_msg(mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                __LINE__, INVALID_USAGE, "PARAMCHECK",
+                                __LINE__, INVALID_USAGE, LayerName,
                                 "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->pQueuePriorities[%d], must be "
                                 "between 0 and 1. Actual value is %f",
                                 i, j, pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j]);
@@ -1555,7 +1567,7 @@
             if (pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex >= properties.size()) {
                 log_msg(
                     mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    INVALID_USAGE, "PARAMCHECK",
+                    INVALID_USAGE, LayerName,
                     "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueFamilyIndex cannot be more than the number "
                     "of queue families.",
                     i);
@@ -1563,7 +1575,7 @@
                        properties[pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex].queueCount) {
                 log_msg(
                     mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    INVALID_USAGE, "PARAMCHECK",
+                    INVALID_USAGE, LayerName,
                     "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueCount cannot be more than the number of "
                     "queues for the given family index.",
                     i);
@@ -1572,6 +1584,59 @@
     }
 }
 
+static void CheckInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
+    VkLayerInstanceDispatchTable *dispatch_table = get_dispatch_table(pc_instance_table_map, instance);
+
+    instance_extension_map[dispatch_table] = {};
+
+    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
+            instance_extension_map[dispatch_table].wsi_enabled = true;
+        }
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
+            instance_extension_map[dispatch_table].xlib_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
+            instance_extension_map[dispatch_table].xcb_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
+            instance_extension_map[dispatch_table].wayland_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_MIR_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
+            instance_extension_map[dispatch_table].mir_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
+            instance_extension_map[dispatch_table].android_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
+            instance_extension_map[dispatch_table].win32_enabled = true;
+        }
+#endif
+    }
+}
+
+static void CheckDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    device_data->wsi_enabled = false;
+
+    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
+            device_data->wsi_enabled = true;
+        }
+    }
+}
+
 void storeCreateDeviceData(VkDevice device, const VkDeviceCreateInfo *pCreateInfo) {
     layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
@@ -1583,8 +1648,7 @@
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice,
-                                            const VkDeviceCreateInfo *pCreateInfo,
+VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
                                             const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
     /*
      * NOTE: We do not validate physicalDevice or any dispatchable
@@ -1592,29 +1656,29 @@
      */
 
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
     assert(my_instance_data != nullptr);
 
-    skipCall |= parameter_validation_vkCreateDevice(my_instance_data->report_data, pCreateInfo, pAllocator, pDevice);
+    skip_call |= parameter_validation_vkCreateDevice(my_instance_data->report_data, pCreateInfo, pAllocator, pDevice);
 
     if (pCreateInfo != NULL) {
         if ((pCreateInfo->enabledLayerCount > 0) && (pCreateInfo->ppEnabledLayerNames != NULL)) {
             for (size_t i = 0; i < pCreateInfo->enabledLayerCount; i++) {
-                skipCall |= validate_string(my_instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledLayerNames",
-                                            pCreateInfo->ppEnabledLayerNames[i]);
+                skip_call |= validate_string(my_instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledLayerNames",
+                                             pCreateInfo->ppEnabledLayerNames[i]);
             }
         }
 
         if ((pCreateInfo->enabledExtensionCount > 0) && (pCreateInfo->ppEnabledExtensionNames != NULL)) {
             for (size_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-                skipCall |= validate_string(my_instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledExtensionNames",
-                                            pCreateInfo->ppEnabledExtensionNames[i]);
+                skip_call |= validate_string(my_instance_data->report_data, "vkCreateDevice",
+                                             "pCreateInfo->ppEnabledExtensionNames", pCreateInfo->ppEnabledExtensionNames[i]);
             }
         }
     }
 
-    if (!skipCall) {
+    if (!skip_call) {
         VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
         assert(chain_info != nullptr);
         assert(chain_info->u.pLayerInfo != nullptr);
@@ -1640,15 +1704,29 @@
             my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
             initDeviceTable(*pDevice, fpGetDeviceProcAddr, pc_device_table_map);
 
+            CheckDeviceRegisterExtensions(pCreateInfo, *pDevice);
+
             uint32_t count;
-            get_dispatch_table(pc_instance_table_map, physicalDevice)
-                ->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
+            VkLayerInstanceDispatchTable *instance_dispatch_table = get_dispatch_table(pc_instance_table_map, physicalDevice);
+            instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
             std::vector<VkQueueFamilyProperties> properties(count);
-            get_dispatch_table(pc_instance_table_map, physicalDevice)
-                ->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, &properties[0]);
+            instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, &properties[0]);
 
             validateDeviceCreateInfo(physicalDevice, pCreateInfo, properties);
             storeCreateDeviceData(*pDevice, pCreateInfo);
+
+            // Query and save physical device limits for this device
+            VkPhysicalDeviceProperties device_properties = {};
+            instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, &device_properties);
+            memcpy(&my_device_data->device_limits, &device_properties.limits, sizeof(VkPhysicalDeviceLimits));
+            my_device_data->physical_device = physicalDevice;
+
+            // Save app-enabled features in this device's layer_data structure
+            if (pCreateInfo->pEnabledFeatures) {
+                my_device_data->physical_device_features = *pCreateInfo->pEnabledFeatures;
+            } else {
+                memset(&my_device_data->physical_device_features, 0, sizeof(VkPhysicalDeviceFeatures));
+            }
         }
     }
 
@@ -1657,13 +1735,13 @@
 
 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
     dispatch_key key = get_dispatch_key(device);
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(key, layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyDevice(my_data->report_data, pAllocator);
+    skip_call |= parameter_validation_vkDestroyDevice(my_data->report_data, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         layer_debug_report_destroy_device(device);
 
 #if DISPATCH_MAP_DEBUG
@@ -1685,41 +1763,38 @@
     const auto &queue_data = my_device_data->queueFamilyIndexMap.find(queueFamilyIndex);
     if (queue_data->second <= queueIndex) {
         log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, INVALID_USAGE,
-                "PARAMCHECK",
+                LayerName,
                 "VkGetDeviceQueue parameter, uint32_t queueIndex %d, must be less than the number of queues given when the device "
                 "was created.",
                 queueIndex);
         return false;
     }
-
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetDeviceQueue(my_data->report_data, queueFamilyIndex, queueIndex, pQueue);
+    skip_call |= parameter_validation_vkGetDeviceQueue(my_data->report_data, queueFamilyIndex, queueIndex, pQueue);
 
-    if (!skipCall) {
+    if (!skip_call) {
         PreGetDeviceQueue(device, queueFamilyIndex, queueIndex);
 
         get_dispatch_table(pc_device_table_map, device)->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
+VKAPI_ATTR VkResult VKAPI_CALL QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkQueueSubmit(my_data->report_data, submitCount, pSubmits, fence);
+    skip_call |= parameter_validation_vkQueueSubmit(my_data->report_data, submitCount, pSubmits, fence);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, queue)->QueueSubmit(queue, submitCount, pSubmits, fence);
 
         validate_result(my_data->report_data, "vkQueueSubmit", result);
@@ -1751,15 +1826,15 @@
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
-                                                                const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
+                                              const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkAllocateMemory(my_data->report_data, pAllocateInfo, pAllocator, pMemory);
+    skip_call |= parameter_validation_vkAllocateMemory(my_data->report_data, pAllocateInfo, pAllocator, pMemory);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
 
         validate_result(my_data->report_data, "vkAllocateMemory", result);
@@ -1768,29 +1843,28 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-FreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL FreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkFreeMemory(my_data->report_data, memory, pAllocator);
+    skip_call |= parameter_validation_vkFreeMemory(my_data->report_data, memory, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->FreeMemory(device, memory, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-MapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) {
+VKAPI_ATTR VkResult VKAPI_CALL MapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size,
+                                         VkMemoryMapFlags flags, void **ppData) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkMapMemory(my_data->report_data, memory, offset, size, flags, ppData);
+    skip_call |= parameter_validation_vkMapMemory(my_data->report_data, memory, offset, size, flags, ppData);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->MapMemory(device, memory, offset, size, flags, ppData);
 
         validate_result(my_data->report_data, "vkMapMemory", result);
@@ -1800,27 +1874,27 @@
 }
 
 VKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory memory) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkUnmapMemory(my_data->report_data, memory);
+    skip_call |= parameter_validation_vkUnmapMemory(my_data->report_data, memory);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->UnmapMemory(device, memory);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-FlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges) {
+VKAPI_ATTR VkResult VKAPI_CALL FlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
+                                                       const VkMappedMemoryRange *pMemoryRanges) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkFlushMappedMemoryRanges(my_data->report_data, memoryRangeCount, pMemoryRanges);
+    skip_call |= parameter_validation_vkFlushMappedMemoryRanges(my_data->report_data, memoryRangeCount, pMemoryRanges);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
 
         validate_result(my_data->report_data, "vkFlushMappedMemoryRanges", result);
@@ -1829,16 +1903,16 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-InvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges) {
+VKAPI_ATTR VkResult VKAPI_CALL InvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
+                                                            const VkMappedMemoryRange *pMemoryRanges) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkInvalidateMappedMemoryRanges(my_data->report_data, memoryRangeCount, pMemoryRanges);
+    skip_call |= parameter_validation_vkInvalidateMappedMemoryRanges(my_data->report_data, memoryRangeCount, pMemoryRanges);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result =
             get_dispatch_table(pc_device_table_map, device)->InvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
 
@@ -1848,15 +1922,15 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceSize *pCommittedMemoryInBytes) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory,
+                                                     VkDeviceSize *pCommittedMemoryInBytes) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetDeviceMemoryCommitment(my_data->report_data, memory, pCommittedMemoryInBytes);
+    skip_call |= parameter_validation_vkGetDeviceMemoryCommitment(my_data->report_data, memory, pCommittedMemoryInBytes);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
     }
 }
@@ -1864,13 +1938,13 @@
 VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory,
                                                 VkDeviceSize memoryOffset) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkBindBufferMemory(my_data->report_data, buffer, memory, memoryOffset);
+    skip_call |= parameter_validation_vkBindBufferMemory(my_data->report_data, buffer, memory, memoryOffset);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->BindBufferMemory(device, buffer, memory, memoryOffset);
 
         validate_result(my_data->report_data, "vkBindBufferMemory", result);
@@ -1879,16 +1953,15 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory,
-                                               VkDeviceSize memoryOffset) {
+VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkBindImageMemory(my_data->report_data, image, memory, memoryOffset);
+    skip_call |= parameter_validation_vkBindImageMemory(my_data->report_data, image, memory, memoryOffset);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->BindImageMemory(device, image, memory, memoryOffset);
 
         validate_result(my_data->report_data, "vkBindImageMemory", result);
@@ -1897,28 +1970,27 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements *pMemoryRequirements) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
+                                                       VkMemoryRequirements *pMemoryRequirements) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetBufferMemoryRequirements(my_data->report_data, buffer, pMemoryRequirements);
+    skip_call |= parameter_validation_vkGetBufferMemoryRequirements(my_data->report_data, buffer, pMemoryRequirements);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetImageMemoryRequirements(my_data->report_data, image, pMemoryRequirements);
+    skip_call |= parameter_validation_vkGetImageMemoryRequirements(my_data->report_data, image, pMemoryRequirements);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->GetImageMemoryRequirements(device, image, pMemoryRequirements);
     }
 }
@@ -1930,7 +2002,7 @@
              (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT |
               VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    UNRECOGNIZED_VALUE, "PARAMCHECK",
+                    UNRECOGNIZED_VALUE, LayerName,
                     "vkGetImageSparseMemoryRequirements parameter, VkImageAspect "
                     "pSparseMemoryRequirements->formatProperties.aspectMask, is an unrecognized enumerator");
             return false;
@@ -1940,17 +2012,16 @@
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
-                                 VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
+                                                            VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetImageSparseMemoryRequirements(my_data->report_data, image, pSparseMemoryRequirementCount,
-                                                               pSparseMemoryRequirements);
+    skip_call |= parameter_validation_vkGetImageSparseMemoryRequirements(my_data->report_data, image, pSparseMemoryRequirementCount,
+                                                                         pSparseMemoryRequirements);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)
             ->GetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
 
@@ -1965,7 +2036,7 @@
         if ((pProperties->aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT |
                                         VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 1,
-                    "PARAMCHECK",
+                    LayerName,
                     "vkGetPhysicalDeviceSparseImageFormatProperties parameter, VkImageAspect pProperties->aspectMask, is an "
                     "unrecognized enumerator");
             return false;
@@ -1975,18 +2046,19 @@
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
-                                             VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling,
-                                             uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+                                                                        VkImageType type, VkSampleCountFlagBits samples,
+                                                                        VkImageUsageFlags usage, VkImageTiling tiling,
+                                                                        uint32_t *pPropertyCount,
+                                                                        VkSparseImageFormatProperties *pProperties) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetPhysicalDeviceSparseImageFormatProperties(my_data->report_data, format, type, samples, usage,
-                                                                           tiling, pPropertyCount, pProperties);
+    skip_call |= parameter_validation_vkGetPhysicalDeviceSparseImageFormatProperties(my_data->report_data, format, type, samples,
+                                                                                     usage, tiling, pPropertyCount, pProperties);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_instance_table_map, physicalDevice)
             ->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, pPropertyCount,
                                                            pProperties);
@@ -1996,16 +2068,16 @@
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence) {
+VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo,
+                                               VkFence fence) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkQueueBindSparse(my_data->report_data, bindInfoCount, pBindInfo, fence);
+    skip_call |= parameter_validation_vkQueueBindSparse(my_data->report_data, bindInfoCount, pBindInfo, fence);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
 
         validate_result(my_data->report_data, "vkQueueBindSparse", result);
@@ -2014,16 +2086,16 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkFence *pFence) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
+                                           const VkAllocationCallbacks *pAllocator, VkFence *pFence) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateFence(my_data->report_data, pCreateInfo, pAllocator, pFence);
+    skip_call |= parameter_validation_vkCreateFence(my_data->report_data, pCreateInfo, pAllocator, pFence);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->CreateFence(device, pCreateInfo, pAllocator, pFence);
 
         validate_result(my_data->report_data, "vkCreateFence", result);
@@ -2033,26 +2105,26 @@
 }
 
 VKAPI_ATTR void VKAPI_CALL DestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyFence(my_data->report_data, fence, pAllocator);
+    skip_call |= parameter_validation_vkDestroyFence(my_data->report_data, fence, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyFence(device, fence, pAllocator);
     }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL ResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkResetFences(my_data->report_data, fenceCount, pFences);
+    skip_call |= parameter_validation_vkResetFences(my_data->report_data, fenceCount, pFences);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->ResetFences(device, fenceCount, pFences);
 
         validate_result(my_data->report_data, "vkResetFences", result);
@@ -2063,13 +2135,13 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL GetFenceStatus(VkDevice device, VkFence fence) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetFenceStatus(my_data->report_data, fence);
+    skip_call |= parameter_validation_vkGetFenceStatus(my_data->report_data, fence);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->GetFenceStatus(device, fence);
 
         validate_result(my_data->report_data, "vkGetFenceStatus", result);
@@ -2078,16 +2150,16 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, uint64_t timeout) {
+VKAPI_ATTR VkResult VKAPI_CALL WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll,
+                                             uint64_t timeout) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkWaitForFences(my_data->report_data, fenceCount, pFences, waitAll, timeout);
+    skip_call |= parameter_validation_vkWaitForFences(my_data->report_data, fenceCount, pFences, waitAll, timeout);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
 
         validate_result(my_data->report_data, "vkWaitForFences", result);
@@ -2097,15 +2169,15 @@
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
-                                                                 const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) {
+                                               const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateSemaphore(my_data->report_data, pCreateInfo, pAllocator, pSemaphore);
+    skip_call |= parameter_validation_vkCreateSemaphore(my_data->report_data, pCreateInfo, pAllocator, pSemaphore);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
 
         validate_result(my_data->report_data, "vkCreateSemaphore", result);
@@ -2114,29 +2186,28 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroySemaphore(my_data->report_data, semaphore, pAllocator);
+    skip_call |= parameter_validation_vkDestroySemaphore(my_data->report_data, semaphore, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroySemaphore(device, semaphore, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
+                                           const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateEvent(my_data->report_data, pCreateInfo, pAllocator, pEvent);
+    skip_call |= parameter_validation_vkCreateEvent(my_data->report_data, pCreateInfo, pAllocator, pEvent);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->CreateEvent(device, pCreateInfo, pAllocator, pEvent);
 
         validate_result(my_data->report_data, "vkCreateEvent", result);
@@ -2146,26 +2217,26 @@
 }
 
 VKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyEvent(my_data->report_data, event, pAllocator);
+    skip_call |= parameter_validation_vkDestroyEvent(my_data->report_data, event, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyEvent(device, event, pAllocator);
     }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL GetEventStatus(VkDevice device, VkEvent event) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetEventStatus(my_data->report_data, event);
+    skip_call |= parameter_validation_vkGetEventStatus(my_data->report_data, event);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->GetEventStatus(device, event);
 
         validate_result(my_data->report_data, "vkGetEventStatus", result);
@@ -2176,13 +2247,13 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL SetEvent(VkDevice device, VkEvent event) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkSetEvent(my_data->report_data, event);
+    skip_call |= parameter_validation_vkSetEvent(my_data->report_data, event);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->SetEvent(device, event);
 
         validate_result(my_data->report_data, "vkSetEvent", result);
@@ -2193,13 +2264,13 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL ResetEvent(VkDevice device, VkEvent event) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkResetEvent(my_data->report_data, event);
+    skip_call |= parameter_validation_vkResetEvent(my_data->report_data, event);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->ResetEvent(device, event);
 
         validate_result(my_data->report_data, "vkResetEvent", result);
@@ -2209,7 +2280,7 @@
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
-                                                const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
+                                               const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
@@ -2241,31 +2312,29 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyQueryPool(my_data->report_data, queryPool, pAllocator);
+    skip_call |= parameter_validation_vkDestroyQueryPool(my_data->report_data, queryPool, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyQueryPool(device, queryPool, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
-                                                   uint32_t queryCount, size_t dataSize, void *pData,
-                                                   VkDeviceSize stride, VkQueryResultFlags flags) {
+VKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
+                                                   size_t dataSize, void *pData, VkDeviceSize stride, VkQueryResultFlags flags) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |=
-        parameter_validation_vkGetQueryPoolResults(my_data->report_data, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
+    skip_call |= parameter_validation_vkGetQueryPoolResults(my_data->report_data, queryPool, firstQuery, queryCount, dataSize,
+                                                            pData, stride, flags);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)
                      ->GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
 
@@ -2275,8 +2344,8 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
+                                            const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
@@ -2321,15 +2390,14 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyBuffer(my_data->report_data, buffer, pAllocator);
+    skip_call |= parameter_validation_vkDestroyBuffer(my_data->report_data, buffer, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyBuffer(device, buffer, pAllocator);
     }
 }
@@ -2337,13 +2405,13 @@
 VKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
                                                 const VkAllocationCallbacks *pAllocator, VkBufferView *pView) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateBufferView(my_data->report_data, pCreateInfo, pAllocator, pView);
+    skip_call |= parameter_validation_vkCreateBufferView(my_data->report_data, pCreateInfo, pAllocator, pView);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->CreateBufferView(device, pCreateInfo, pAllocator, pView);
 
         validate_result(my_data->report_data, "vkCreateBufferView", result);
@@ -2352,15 +2420,14 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyBufferView(my_data->report_data, bufferView, pAllocator);
+    skip_call |= parameter_validation_vkDestroyBufferView(my_data->report_data, bufferView, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyBufferView(device, bufferView, pAllocator);
     }
 }
@@ -2401,26 +2468,22 @@
         }
 
         // width, height, and depth members of extent must be greater than 0
-        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.width", pCreateInfo->extent.width,
-                                           0u);
-        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.height", pCreateInfo->extent.height,
-                                           0u);
-        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.depth", pCreateInfo->extent.depth,
-                                           0u);
+        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.width", pCreateInfo->extent.width, 0u);
+        skip_call |=
+            ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.height", pCreateInfo->extent.height, 0u);
+        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.depth", pCreateInfo->extent.depth, 0u);
 
         // mipLevels must be greater than 0
-        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->mipLevels", pCreateInfo->mipLevels,
-                                           0u);
+        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->mipLevels", pCreateInfo->mipLevels, 0u);
 
         // arrayLayers must be greater than 0
-        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->arrayLayers", pCreateInfo->arrayLayers,
-                                           0u);
+        skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->arrayLayers", pCreateInfo->arrayLayers, 0u);
 
         // If imageType is VK_IMAGE_TYPE_1D, both extent.height and extent.depth must be 1
         if ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) && (pCreateInfo->extent.height != 1) && (pCreateInfo->extent.depth != 1)) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
                                  LayerName, "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_1D, both "
-                                                          "pCreateInfo->extent.height and pCreateInfo->extent.depth must be 1");
+                                            "pCreateInfo->extent.height and pCreateInfo->extent.depth must be 1");
         }
 
         if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D) {
@@ -2428,17 +2491,15 @@
             // extent.height must be equal
             if ((pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
                 (pCreateInfo->extent.width != pCreateInfo->extent.height)) {
-                skip_call |=
-                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
-                            LayerName, "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_2D and "
-                                                     "pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, "
-                                                     "pCreateInfo->extent.width and pCreateInfo->extent.height must be equal");
+                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
+                                     LayerName, "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_2D and "
+                                                "pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, "
+                                                "pCreateInfo->extent.width and pCreateInfo->extent.height must be equal");
             }
 
             if (pCreateInfo->extent.depth != 1) {
                 skip_call |=
-                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
-                            LayerName,
+                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName,
                             "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_2D, pCreateInfo->extent.depth must be 1");
             }
         }
@@ -2446,20 +2507,20 @@
         // mipLevels must be less than or equal to floor(log2(max(extent.width,extent.height,extent.depth)))+1
         uint32_t maxDim = std::max(std::max(pCreateInfo->extent.width, pCreateInfo->extent.height), pCreateInfo->extent.depth);
         if (pCreateInfo->mipLevels > (floor(log2(maxDim)) + 1)) {
-            skip_call |= log_msg(
-                report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName,
-                "vkCreateImage: pCreateInfo->mipLevels must be less than or equal to "
-                "floor(log2(max(pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth)))+1");
+            skip_call |=
+                log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName,
+                        "vkCreateImage: pCreateInfo->mipLevels must be less than or equal to "
+                        "floor(log2(max(pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth)))+1");
         }
 
         // If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain
         // VK_IMAGE_CREATE_SPARSE_BINDING_BIT
         if (((pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT)) != 0) &&
             ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
-            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
-                                 LayerName,
-                                 "vkCreateImage: pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or "
-                                 "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT");
+            skip_call |=
+                log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName,
+                        "vkCreateImage: pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or "
+                        "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT");
         }
     }
 
@@ -2473,13 +2534,13 @@
 }
 
 VKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyImage(my_data->report_data, image, pAllocator);
+    skip_call |= parameter_validation_vkDestroyImage(my_data->report_data, image, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyImage(device, image, pAllocator);
     }
 }
@@ -2489,7 +2550,7 @@
         if ((pSubresource->aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT |
                                          VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    UNRECOGNIZED_VALUE, "PARAMCHECK",
+                    UNRECOGNIZED_VALUE, LayerName,
                     "vkGetImageSubresourceLayout parameter, VkImageAspect pSubresource->aspectMask, is an unrecognized enumerator");
             return false;
         }
@@ -2498,15 +2559,15 @@
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource,
+                                                     VkSubresourceLayout *pLayout) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetImageSubresourceLayout(my_data->report_data, image, pSubresource, pLayout);
+    skip_call |= parameter_validation_vkGetImageSubresourceLayout(my_data->report_data, image, pSubresource, pLayout);
 
-    if (!skipCall) {
+    if (!skip_call) {
         PreGetImageSubresourceLayout(device, pSubresource);
 
         get_dispatch_table(pc_device_table_map, device)->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
@@ -2525,28 +2586,32 @@
 
     if (pCreateInfo != nullptr) {
         if ((pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D) || (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_2D)) {
-            if (pCreateInfo->subresourceRange.layerCount != 1) {
+            if ((pCreateInfo->subresourceRange.layerCount != 1) &&
+                (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
                                      LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_%dD, "
                                                 "pCreateInfo->subresourceRange.layerCount must be 1",
                                      ((pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D) ? 1 : 2));
             }
         } else if ((pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY) ||
-                   (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)) {
-            if (pCreateInfo->subresourceRange.layerCount < 1) {
+                   (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY)) {
+            if ((pCreateInfo->subresourceRange.layerCount < 1) &&
+                (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
                                      LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_%dD_ARRAY, "
                                                 "pCreateInfo->subresourceRange.layerCount must be >= 1",
                                      ((pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? 1 : 2));
             }
         } else if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE) {
-            if (pCreateInfo->subresourceRange.layerCount != 6) {
+            if ((pCreateInfo->subresourceRange.layerCount != 6) &&
+                (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
                                      LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_CUBE, "
                                                 "pCreateInfo->subresourceRange.layerCount must be 6");
             }
         } else if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
-            if ((pCreateInfo->subresourceRange.layerCount == 0) || ((pCreateInfo->subresourceRange.layerCount % 6) != 0)) {
+            if (((pCreateInfo->subresourceRange.layerCount == 0) || ((pCreateInfo->subresourceRange.layerCount % 6) != 0)) &&
+                (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
                                      LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_CUBE_ARRAY, "
                                                 "pCreateInfo->subresourceRange.layerCount must be a multiple of 6");
@@ -2558,7 +2623,8 @@
                                                 "pCreateInfo->subresourceRange.baseArrayLayer must be 0");
             }
 
-            if (pCreateInfo->subresourceRange.layerCount != 1) {
+            if ((pCreateInfo->subresourceRange.layerCount != 1) &&
+                (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1,
                                      LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_3D, "
                                                 "pCreateInfo->subresourceRange.layerCount must be 1");
@@ -2575,30 +2641,28 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyImageView(my_data->report_data, imageView, pAllocator);
+    skip_call |= parameter_validation_vkDestroyImageView(my_data->report_data, imageView, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyImageView(device, imageView, pAllocator);
     }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
-                                                  const VkAllocationCallbacks *pAllocator,
-                                                  VkShaderModule *pShaderModule) {
+                                                  const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateShaderModule(my_data->report_data, pCreateInfo, pAllocator, pShaderModule);
+    skip_call |= parameter_validation_vkCreateShaderModule(my_data->report_data, pCreateInfo, pAllocator, pShaderModule);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result =
             get_dispatch_table(pc_device_table_map, device)->CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
 
@@ -2608,30 +2672,29 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
+                                               const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyShaderModule(my_data->report_data, shaderModule, pAllocator);
+    skip_call |= parameter_validation_vkDestroyShaderModule(my_data->report_data, shaderModule, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyShaderModule(device, shaderModule, pAllocator);
     }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo,
-                                                   const VkAllocationCallbacks *pAllocator,
-                                                   VkPipelineCache *pPipelineCache) {
+                                                   const VkAllocationCallbacks *pAllocator, VkPipelineCache *pPipelineCache) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreatePipelineCache(my_data->report_data, pCreateInfo, pAllocator, pPipelineCache);
+    skip_call |= parameter_validation_vkCreatePipelineCache(my_data->report_data, pCreateInfo, pAllocator, pPipelineCache);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result =
             get_dispatch_table(pc_device_table_map, device)->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
 
@@ -2641,29 +2704,29 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache,
+                                                const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyPipelineCache(my_data->report_data, pipelineCache, pAllocator);
+    skip_call |= parameter_validation_vkDestroyPipelineCache(my_data->report_data, pipelineCache, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyPipelineCache(device, pipelineCache, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize, void *pData) {
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize,
+                                                    void *pData) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetPipelineCacheData(my_data->report_data, pipelineCache, pDataSize, pData);
+    skip_call |= parameter_validation_vkGetPipelineCacheData(my_data->report_data, pipelineCache, pDataSize, pData);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
 
         validate_result(my_data->report_data, "vkGetPipelineCacheData", result);
@@ -2672,16 +2735,16 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches) {
+VKAPI_ATTR VkResult VKAPI_CALL MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount,
+                                                   const VkPipelineCache *pSrcCaches) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkMergePipelineCaches(my_data->report_data, dstCache, srcCacheCount, pSrcCaches);
+    skip_call |= parameter_validation_vkMergePipelineCaches(my_data->report_data, dstCache, srcCacheCount, pSrcCaches);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
 
         validate_result(my_data->report_data, "vkMergePipelineCaches", result);
@@ -2699,7 +2762,7 @@
             if (pCreateInfos->basePipelineIndex != -1) {
                 if (pCreateInfos->basePipelineHandle != VK_NULL_HANDLE) {
                     log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                            INVALID_USAGE, "PARAMCHECK",
+                            INVALID_USAGE, LayerName,
                             "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineHandle, must be VK_NULL_HANDLE if "
                             "pCreateInfos->flags "
                             "contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag and pCreateInfos->basePipelineIndex is not -1");
@@ -2711,7 +2774,7 @@
                 if (pCreateInfos->basePipelineIndex != -1) {
                     log_msg(
                         mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                        INVALID_USAGE, "PARAMCHECK",
+                        INVALID_USAGE, LayerName,
                         "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineIndex, must be -1 if pCreateInfos->flags "
                         "contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag and pCreateInfos->basePipelineHandle is not "
                         "VK_NULL_HANDLE");
@@ -2723,7 +2786,7 @@
         if (pCreateInfos->pRasterizationState != nullptr) {
             if (pCreateInfos->pRasterizationState->cullMode & ~VK_CULL_MODE_FRONT_AND_BACK) {
                 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                        UNRECOGNIZED_VALUE, "PARAMCHECK",
+                        UNRECOGNIZED_VALUE, LayerName,
                         "vkCreateGraphicsPipelines parameter, VkCullMode pCreateInfos->pRasterizationState->cullMode, is an "
                         "unrecognized enumerator");
                 return false;
@@ -2740,10 +2803,9 @@
     return true;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
-                        const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
-                        VkPipeline *pPipelines) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
+                                                       const VkGraphicsPipelineCreateInfo *pCreateInfos,
+                                                       const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
@@ -2780,12 +2842,22 @@
                                              i, i);
                     }
                 }
-            } else if (pCreateInfos[i].pTessellationState->sType != VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO) {
-                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                     __LINE__, INVALID_STRUCT_STYPE, LayerName,
-                                     "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pTessellationState->sType must be "
-                                     "VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO",
-                                     i);
+            } else {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState->pNext",
+                                          NULL, pCreateInfos[i].pTessellationState->pNext, 0, NULL, GeneratedHeaderVersion);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState->flags",
+                                            pCreateInfos[i].pTessellationState->flags);
+
+                if (pCreateInfos[i].pTessellationState->sType != VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO) {
+                    skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                                         __LINE__, INVALID_STRUCT_STYPE, LayerName,
+                                         "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pTessellationState->sType must be "
+                                         "VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO",
+                                         i);
+                }
             }
 
             if (pCreateInfos[i].pViewportState == nullptr) {
@@ -2801,6 +2873,14 @@
                         i, i);
                 }
             } else {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pViewportState->pNext", NULL,
+                                          pCreateInfos[i].pViewportState->pNext, 0, NULL, GeneratedHeaderVersion);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pViewportState->flags",
+                                            pCreateInfos[i].pViewportState->flags);
+
                 if (pCreateInfos[i].pViewportState->sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) {
                     skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                          __LINE__, INVALID_STRUCT_STYPE, LayerName,
@@ -2879,26 +2959,181 @@
                                                                "VK_FALSE, pCreateInfos[%d].pMultisampleState must not be NULL",
                                 i, i);
                 }
-            } else if (pCreateInfos[i].pMultisampleState->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) {
-                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                     __LINE__, INVALID_STRUCT_STYPE, LayerName,
-                                     "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pMultisampleState->sType must be "
-                                     "VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO",
-                                     i);
+            } else {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->pNext",
+                                          NULL, pCreateInfos[i].pMultisampleState->pNext, 0, NULL, GeneratedHeaderVersion);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->flags",
+                                            pCreateInfos[i].pMultisampleState->flags);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pMultisampleState->sampleShadingEnable",
+                                             pCreateInfos[i].pMultisampleState->sampleShadingEnable);
+
+                skip_call |= validate_array(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->rasterizationSamples",
+                    "pCreateInfos[i].pMultisampleState->pSampleMask", pCreateInfos[i].pMultisampleState->rasterizationSamples,
+                    pCreateInfos[i].pMultisampleState->pSampleMask, true, false);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pMultisampleState->alphaToCoverageEnable",
+                                             pCreateInfos[i].pMultisampleState->alphaToCoverageEnable);
+
+                skip_call |=
+                    validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->alphaToOneEnable",
+                                    pCreateInfos[i].pMultisampleState->alphaToOneEnable);
+
+                if (pCreateInfos[i].pMultisampleState->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) {
+                    skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                                         __LINE__, INVALID_STRUCT_STYPE, LayerName,
+                                         "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pMultisampleState->sType must be "
+                                         "VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO",
+                                         i);
+                }
             }
 
             // TODO: Conditional NULL check based on rasterizerDiscardEnable and subpass
-            if ((pCreateInfos[i].pDepthStencilState != nullptr) &&
-                (pCreateInfos[i].pDepthStencilState->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)) {
-                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                     __LINE__, INVALID_STRUCT_STYPE, LayerName,
-                                     "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pDepthStencilState->sType must be "
-                                     "VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO",
-                                     i);
+            if (pCreateInfos[i].pDepthStencilState != nullptr) {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->pNext",
+                                          NULL, pCreateInfos[i].pDepthStencilState->pNext, 0, NULL, GeneratedHeaderVersion);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->flags",
+                                            pCreateInfos[i].pDepthStencilState->flags);
+
+                skip_call |=
+                    validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->depthTestEnable",
+                                    pCreateInfos[i].pDepthStencilState->depthTestEnable);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pDepthStencilState->depthWriteEnable",
+                                             pCreateInfos[i].pDepthStencilState->depthWriteEnable);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->depthCompareOp", "VkCompareOp",
+                    VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->depthCompareOp);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable",
+                                             pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable);
+
+                skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                             "pCreateInfos[i].pDepthStencilState->stencilTestEnable",
+                                             pCreateInfos[i].pDepthStencilState->stencilTestEnable);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.failOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.failOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.passOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.passOp);
+
+                skip_call |= validate_ranged_enum(report_data, "vkCreateGraphicsPipelines",
+                                                  "pCreateInfos[i].pDepthStencilState->front.depthFailOp", "VkStencilOp",
+                                                  VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE,
+                                                  pCreateInfos[i].pDepthStencilState->front.depthFailOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.compareOp", "VkCompareOp",
+                    VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.compareOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.failOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.failOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.passOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.passOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.depthFailOp", "VkStencilOp",
+                    VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.depthFailOp);
+
+                skip_call |= validate_ranged_enum(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.compareOp", "VkCompareOp",
+                    VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.compareOp);
+
+                if (pCreateInfos[i].pDepthStencilState->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) {
+                    skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                                         __LINE__, INVALID_STRUCT_STYPE, LayerName,
+                                         "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pDepthStencilState->sType must be "
+                                         "VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO",
+                                         i);
+                }
             }
 
             // TODO: Conditional NULL check based on rasterizerDiscardEnable and subpass
             if (pCreateInfos[i].pColorBlendState != nullptr) {
+                skip_call |=
+                    validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->pNext", NULL,
+                                          pCreateInfos[i].pColorBlendState->pNext, 0, NULL, GeneratedHeaderVersion);
+
+                skip_call |=
+                    validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->flags",
+                                            pCreateInfos[i].pColorBlendState->flags);
+
+                skip_call |=
+                    validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->logicOpEnable",
+                                    pCreateInfos[i].pColorBlendState->logicOpEnable);
+
+                skip_call |= validate_array(
+                    report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->attachmentCount",
+                    "pCreateInfos[i].pColorBlendState->pAttachments", pCreateInfos[i].pColorBlendState->attachmentCount,
+                    pCreateInfos[i].pColorBlendState->pAttachments, false, true);
+
+                if (pCreateInfos[i].pColorBlendState->pAttachments != NULL) {
+                    for (uint32_t attachmentIndex = 0; attachmentIndex < pCreateInfos[i].pColorBlendState->attachmentCount;
+                         ++attachmentIndex) {
+                        skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines",
+                                                     "pCreateInfos[i].pColorBlendState->pAttachments[i].blendEnable",
+                                                     pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].blendEnable);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].srcColorBlendFactor", "VkBlendFactor",
+                            VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE,
+                            pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcColorBlendFactor);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].dstColorBlendFactor", "VkBlendFactor",
+                            VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE,
+                            pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstColorBlendFactor);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].colorBlendOp", "VkBlendOp", VK_BLEND_OP_BEGIN_RANGE,
+                            VK_BLEND_OP_END_RANGE, pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorBlendOp);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].srcAlphaBlendFactor", "VkBlendFactor",
+                            VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE,
+                            pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcAlphaBlendFactor);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].dstAlphaBlendFactor", "VkBlendFactor",
+                            VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE,
+                            pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstAlphaBlendFactor);
+
+                        skip_call |= validate_ranged_enum(
+                            report_data, "vkCreateGraphicsPipelines",
+                            "pCreateInfos[i].pColorBlendState->pAttachments[i].alphaBlendOp", "VkBlendOp", VK_BLEND_OP_BEGIN_RANGE,
+                            VK_BLEND_OP_END_RANGE, pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].alphaBlendOp);
+
+                        skip_call |=
+                            validate_flags(report_data, "vkCreateGraphicsPipelines",
+                                           "pCreateInfos[i].pColorBlendState->pAttachments[i].colorWriteMask",
+                                           "VkColorComponentFlagBits", AllVkColorComponentFlagBits,
+                                           pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorWriteMask, false);
+                    }
+                }
+
                 if (pCreateInfos[i].pColorBlendState->sType != VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO) {
                     skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                          __LINE__, INVALID_STRUCT_STYPE, LayerName,
@@ -2941,19 +3176,18 @@
     return true;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
-                       const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
-                       VkPipeline *pPipelines) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
+                                                      const VkComputePipelineCreateInfo *pCreateInfos,
+                                                      const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateComputePipelines(my_data->report_data, pipelineCache, createInfoCount, pCreateInfos, pAllocator,
-                                                     pPipelines);
+    skip_call |= parameter_validation_vkCreateComputePipelines(my_data->report_data, pipelineCache, createInfoCount, pCreateInfos,
+                                                               pAllocator, pPipelines);
 
-    if (!skipCall) {
+    if (!skip_call) {
         PreCreateComputePipelines(device, pCreateInfos);
 
         result = get_dispatch_table(pc_device_table_map, device)
@@ -2965,30 +3199,28 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyPipeline(my_data->report_data, pipeline, pAllocator);
+    skip_call |= parameter_validation_vkDestroyPipeline(my_data->report_data, pipeline, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyPipeline(device, pipeline, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
-                     VkPipelineLayout *pPipelineLayout) {
+VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
+                                                    const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreatePipelineLayout(my_data->report_data, pCreateInfo, pAllocator, pPipelineLayout);
+    skip_call |= parameter_validation_vkCreatePipelineLayout(my_data->report_data, pCreateInfo, pAllocator, pPipelineLayout);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result =
             get_dispatch_table(pc_device_table_map, device)->CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
 
@@ -2998,15 +3230,15 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
+                                                 const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyPipelineLayout(my_data->report_data, pipelineLayout, pAllocator);
+    skip_call |= parameter_validation_vkDestroyPipelineLayout(my_data->report_data, pipelineLayout, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
     }
 }
@@ -3048,22 +3280,21 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroySampler(my_data->report_data, sampler, pAllocator);
+    skip_call |= parameter_validation_vkDestroySampler(my_data->report_data, sampler, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroySampler(device, sampler, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
-                          const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
+                                                         const VkAllocationCallbacks *pAllocator,
+                                                         VkDescriptorSetLayout *pSetLayout) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
@@ -3119,32 +3350,31 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
+                                                      const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyDescriptorSetLayout(my_data->report_data, descriptorSetLayout, pAllocator);
+    skip_call |= parameter_validation_vkDestroyDescriptorSetLayout(my_data->report_data, descriptorSetLayout, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
-                     VkDescriptorPool *pDescriptorPool) {
+VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
+                                                    const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateDescriptorPool(my_data->report_data, pCreateInfo, pAllocator, pDescriptorPool);
+    skip_call |= parameter_validation_vkCreateDescriptorPool(my_data->report_data, pCreateInfo, pAllocator, pDescriptorPool);
 
     /* TODOVV: How do we validate maxSets? Probably belongs in the limits layer? */
 
-    if (!skipCall) {
+    if (!skip_call) {
         result =
             get_dispatch_table(pc_device_table_map, device)->CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
 
@@ -3154,29 +3384,29 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
+                                                 const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyDescriptorPool(my_data->report_data, descriptorPool, pAllocator);
+    skip_call |= parameter_validation_vkDestroyDescriptorPool(my_data->report_data, descriptorPool, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags) {
+VKAPI_ATTR VkResult VKAPI_CALL ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
+                                                   VkDescriptorPoolResetFlags flags) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkResetDescriptorPool(my_data->report_data, descriptorPool, flags);
+    skip_call |= parameter_validation_vkResetDescriptorPool(my_data->report_data, descriptorPool, flags);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->ResetDescriptorPool(device, descriptorPool, flags);
 
         validate_result(my_data->report_data, "vkResetDescriptorPool", result);
@@ -3185,16 +3415,16 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets) {
+VKAPI_ATTR VkResult VKAPI_CALL AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
+                                                      VkDescriptorSet *pDescriptorSets) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkAllocateDescriptorSets(my_data->report_data, pAllocateInfo, pDescriptorSets);
+    skip_call |= parameter_validation_vkAllocateDescriptorSets(my_data->report_data, pAllocateInfo, pDescriptorSets);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
 
         validate_result(my_data->report_data, "vkAllocateDescriptorSets", result);
@@ -3203,8 +3433,7 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
-                                                  uint32_t descriptorSetCount,
+VKAPI_ATTR VkResult VKAPI_CALL FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
                                                   const VkDescriptorSet *pDescriptorSets) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
@@ -3230,9 +3459,9 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites,
-                     uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) {
+VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
+                                                const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount,
+                                                const VkCopyDescriptorSet *pDescriptorCopies) {
     bool skip_call = false;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(device_data != NULL);
@@ -3298,6 +3527,12 @@
                                          "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "
                                          "pDescriptorWrites[%d].pBufferInfo must not be NULL",
                                          i, i);
+                } else {
+                    for (uint32_t descriptorIndex = 0; descriptorIndex < pDescriptorWrites[i].descriptorCount; ++descriptorIndex) {
+                        skip_call |= validate_required_handle(report_data, "vkUpdateDescriptorSets",
+                                                              "pDescriptorWrites[i].pBufferInfo[i].buffer",
+                                                              pDescriptorWrites[i].pBufferInfo[descriptorIndex].buffer);
+                    }
                 }
             } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
                        (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
@@ -3319,6 +3554,38 @@
                     }
                 }
             }
+
+            if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
+                (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
+                VkDeviceSize uniformAlignment = device_data->device_limits.minUniformBufferOffsetAlignment;
+                for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
+                    if (pDescriptorWrites[i].pBufferInfo != NULL) {
+                        if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) {
+                            skip_call |=
+                                log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                        VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVICE_LIMIT, LayerName,
+                                        "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
+                                        ") must be a multiple of device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64,
+                                        i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment);
+                        }
+                    }
+                }
+            } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
+                       (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
+                VkDeviceSize storageAlignment = device_data->device_limits.minStorageBufferOffsetAlignment;
+                for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
+                    if (pDescriptorWrites[i].pBufferInfo != NULL) {
+                        if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) {
+                            skip_call |=
+                                log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                        VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVICE_LIMIT, LayerName,
+                                        "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
+                                        ") must be a multiple of device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64,
+                                        i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment);
+                        }
+                    }
+                }
+            }
         }
     }
 
@@ -3329,16 +3596,15 @@
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
-                                                 const VkAllocationCallbacks *pAllocator,
-                                                                   VkFramebuffer *pFramebuffer) {
+                                                 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateFramebuffer(my_data->report_data, pCreateInfo, pAllocator, pFramebuffer);
+    skip_call |= parameter_validation_vkCreateFramebuffer(my_data->report_data, pCreateInfo, pAllocator, pFramebuffer);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
 
         validate_result(my_data->report_data, "vkCreateFramebuffer", result);
@@ -3347,30 +3613,43 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyFramebuffer(my_data->report_data, framebuffer, pAllocator);
+    skip_call |= parameter_validation_vkDestroyFramebuffer(my_data->report_data, framebuffer, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyFramebuffer(device, framebuffer, pAllocator);
     }
 }
 
+bool PreCreateRenderPass(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo) {
+    bool skip_call = false;
+    uint32_t max_color_attachments = dev_data->device_limits.maxColorAttachments;
+
+    for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
+        if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) {
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                                 __LINE__, DEVICE_LIMIT, "DL", "Cannot create a render pass with %d color attachments. Max is %d.",
+                                 pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments);
+        }
+    }
+    return skip_call;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
-                                                const VkAllocationCallbacks *pAllocator,
-                                                VkRenderPass *pRenderPass) {
+                                                const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCreateRenderPass(my_data->report_data, pCreateInfo, pAllocator, pRenderPass);
+    skip_call |= parameter_validation_vkCreateRenderPass(my_data->report_data, pCreateInfo, pAllocator, pRenderPass);
+    skip_call |= PreCreateRenderPass(my_data, pCreateInfo);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
 
         validate_result(my_data->report_data, "vkCreateRenderPass", result);
@@ -3379,46 +3658,43 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyRenderPass(my_data->report_data, renderPass, pAllocator);
+    skip_call |= parameter_validation_vkDestroyRenderPass(my_data->report_data, renderPass, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyRenderPass(device, renderPass, pAllocator);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-GetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D *pGranularity) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL GetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D *pGranularity) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkGetRenderAreaGranularity(my_data->report_data, renderPass, pGranularity);
+    skip_call |= parameter_validation_vkGetRenderAreaGranularity(my_data->report_data, renderPass, pGranularity);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->GetRenderAreaGranularity(device, renderPass, pGranularity);
     }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
-                                                 const VkAllocationCallbacks *pAllocator,
-                                                 VkCommandPool *pCommandPool) {
+                                                 const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |=
+    skip_call |=
         validate_queue_family_index(my_data, "vkCreateCommandPool", "pCreateInfo->queueFamilyIndex", pCreateInfo->queueFamilyIndex);
 
-    skipCall |= parameter_validation_vkCreateCommandPool(my_data->report_data, pCreateInfo, pAllocator, pCommandPool);
+    skip_call |= parameter_validation_vkCreateCommandPool(my_data->report_data, pCreateInfo, pAllocator, pCommandPool);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
 
         validate_result(my_data->report_data, "vkCreateCommandPool", result);
@@ -3427,29 +3703,27 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkDestroyCommandPool(my_data->report_data, commandPool, pAllocator);
+    skip_call |= parameter_validation_vkDestroyCommandPool(my_data->report_data, commandPool, pAllocator);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
+VKAPI_ATTR VkResult VKAPI_CALL ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkResetCommandPool(my_data->report_data, commandPool, flags);
+    skip_call |= parameter_validation_vkResetCommandPool(my_data->report_data, commandPool, flags);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->ResetCommandPool(device, commandPool, flags);
 
         validate_result(my_data->report_data, "vkResetCommandPool", result);
@@ -3458,16 +3732,16 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers) {
+VKAPI_ATTR VkResult VKAPI_CALL AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
+                                                      VkCommandBuffer *pCommandBuffers) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkAllocateCommandBuffers(my_data->report_data, pAllocateInfo, pCommandBuffers);
+    skip_call |= parameter_validation_vkAllocateCommandBuffers(my_data->report_data, pAllocateInfo, pCommandBuffers);
 
-    if (!skipCall) {
+    if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, device)->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
 
         validate_result(my_data->report_data, "vkAllocateCommandBuffers", result);
@@ -3476,8 +3750,7 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
-                                              uint32_t commandBufferCount,
+VKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
                                               const VkCommandBuffer *pCommandBuffers) {
     bool skip_call = false;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
@@ -3498,8 +3771,34 @@
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
+bool PreBeginCommandBuffer(layer_data *dev_data, VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
+    bool skip_call = false;
+    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(dev_data->physical_device), layer_data_map);
+    const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
+
+    if (pInfo != NULL) {
+        if ((phy_dev_data->physical_device_features.inheritedQueries == VK_FALSE) && (pInfo->occlusionQueryEnable != VK_FALSE)) {
+            skip_call |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                        reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVICE_FEATURE, LayerName,
+                        "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support "
+                        "inheritedQueries.");
+        }
+
+        if ((phy_dev_data->physical_device_features.inheritedQueries != VK_FALSE) && (pInfo->occlusionQueryEnable != VK_FALSE) &&
+            (!validate_VkQueryControlFlagBits(VkQueryControlFlagBits(pInfo->queryFlags)))) {
+            skip_call |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                        reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVICE_FEATURE, LayerName,
+                        "Cannot enable in occlusion queries in vkBeginCommandBuffer() and set queryFlags to %d which is not a "
+                        "valid combination of VkQueryControlFlagBits.",
+                        pInfo->queryFlags);
+        }
+    }
+    return skip_call;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
@@ -3515,6 +3814,12 @@
                                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, false);
 
     if (pBeginInfo->pInheritanceInfo != NULL) {
+        skip_call |= validate_struct_pnext(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->pNext", NULL,
+                                           pBeginInfo->pInheritanceInfo->pNext, 0, NULL, GeneratedHeaderVersion);
+
+        skip_call |= validate_bool32(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->occlusionQueryEnable",
+                                     pBeginInfo->pInheritanceInfo->occlusionQueryEnable);
+
         // TODO: This only needs to be validated when the inherited queries feature is enabled
         // skip_call |= validate_flags(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->queryFlags",
         // "VkQueryControlFlagBits", AllVkQueryControlFlagBits, pBeginInfo->pInheritanceInfo->queryFlags, false);
@@ -3525,6 +3830,8 @@
                                     pBeginInfo->pInheritanceInfo->pipelineStatistics, false);
     }
 
+    skip_call |= PreBeginCommandBuffer(device_data, commandBuffer, pBeginInfo);
+
     if (!skip_call) {
         result = get_dispatch_table(pc_device_table_map, commandBuffer)->BeginCommandBuffer(commandBuffer, pBeginInfo);
 
@@ -3545,8 +3852,7 @@
     return result;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) {
+VKAPI_ATTR VkResult VKAPI_CALL ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
@@ -3562,42 +3868,42 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
+                                           VkPipeline pipeline) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdBindPipeline(my_data->report_data, pipelineBindPoint, pipeline);
+    skip_call |= parameter_validation_vkCmdBindPipeline(my_data->report_data, pipelineBindPoint, pipeline);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
+                                          const VkViewport *pViewports) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdSetViewport(my_data->report_data, firstViewport, viewportCount, pViewports);
+    skip_call |= parameter_validation_vkCmdSetViewport(my_data->report_data, firstViewport, viewportCount, pViewports);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
+                                         const VkRect2D *pScissors) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdSetScissor(my_data->report_data, firstScissor, scissorCount, pScissors);
+    skip_call |= parameter_validation_vkCmdSetScissor(my_data->report_data, firstScissor, scissorCount, pScissors);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
     }
 }
@@ -3606,109 +3912,106 @@
     get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetLineWidth(commandBuffer, lineWidth);
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor) {
+VKAPI_ATTR void VKAPI_CALL CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp,
+                                           float depthBiasSlopeFactor) {
     get_dispatch_table(pc_device_table_map, commandBuffer)
         ->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdSetBlendConstants(my_data->report_data, blendConstants);
+    skip_call |= parameter_validation_vkCmdSetBlendConstants(my_data->report_data, blendConstants);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetBlendConstants(commandBuffer, blendConstants);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) {
+VKAPI_ATTR void VKAPI_CALL CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) {
     get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+                                                    uint32_t compareMask) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdSetStencilCompareMask(my_data->report_data, faceMask, compareMask);
+    skip_call |= parameter_validation_vkCmdSetStencilCompareMask(my_data->report_data, faceMask, compareMask);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdSetStencilWriteMask(my_data->report_data, faceMask, writeMask);
+    skip_call |= parameter_validation_vkCmdSetStencilWriteMask(my_data->report_data, faceMask, writeMask);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdSetStencilReference(my_data->report_data, faceMask, reference);
+    skip_call |= parameter_validation_vkCmdSetStencilReference(my_data->report_data, faceMask, reference);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetStencilReference(commandBuffer, faceMask, reference);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
-                      uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets,
-                      uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
+                                                 VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount,
+                                                 const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
+                                                 const uint32_t *pDynamicOffsets) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdBindDescriptorSets(my_data->report_data, pipelineBindPoint, layout, firstSet, descriptorSetCount,
-                                                    pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
+    skip_call |=
+        parameter_validation_vkCmdBindDescriptorSets(my_data->report_data, pipelineBindPoint, layout, firstSet, descriptorSetCount,
+                                                     pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets,
                                     dynamicOffsetCount, pDynamicOffsets);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
+                                              VkIndexType indexType) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdBindIndexBuffer(my_data->report_data, buffer, offset, indexType);
+    skip_call |= parameter_validation_vkCmdBindIndexBuffer(my_data->report_data, buffer, offset, indexType);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
-                                                uint32_t bindingCount, const VkBuffer *pBuffers,
-                                                const VkDeviceSize *pOffsets) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount,
+                                                const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdBindVertexBuffers(my_data->report_data, firstBinding, bindingCount, pBuffers, pOffsets);
+    skip_call |= parameter_validation_vkCmdBindVertexBuffers(my_data->report_data, firstBinding, bindingCount, pBuffers, pOffsets);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
     }
@@ -3720,7 +4023,7 @@
         // TODO: Verify against Valid Usage section. I don't see a non-zero vertexCount listed, may need to add that and make
         // this an error or leave as is.
         log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                REQUIRED_PARAMETER, "PARAMCHECK", "vkCmdDraw parameter, uint32_t vertexCount, is 0");
+                REQUIRED_PARAMETER, LayerName, "vkCmdDraw parameter, uint32_t vertexCount, is 0");
         return false;
     }
 
@@ -3728,7 +4031,7 @@
         // TODO: Verify against Valid Usage section. I don't see a non-zero instanceCount listed, may need to add that and make
         // this an error or leave as is.
         log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                REQUIRED_PARAMETER, "PARAMCHECK", "vkCmdDraw parameter, uint32_t instanceCount, is 0");
+                REQUIRED_PARAMETER, LayerName, "vkCmdDraw parameter, uint32_t instanceCount, is 0");
         return false;
     }
 
@@ -3743,35 +4046,34 @@
         ->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
 }
 
-VKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
-                                          uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
-                                          uint32_t firstInstance) {
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
+                                          uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
     get_dispatch_table(pc_device_table_map, commandBuffer)
         ->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
+                                           uint32_t stride) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdDrawIndirect(my_data->report_data, buffer, offset, count, stride);
+    skip_call |= parameter_validation_vkCmdDrawIndirect(my_data->report_data, buffer, offset, count, stride);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
+                                                  uint32_t count, uint32_t stride) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdDrawIndexedIndirect(my_data->report_data, buffer, offset, count, stride);
+    skip_call |= parameter_validation_vkCmdDrawIndexedIndirect(my_data->report_data, buffer, offset, count, stride);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
     }
@@ -3781,28 +4083,27 @@
     get_dispatch_table(pc_device_table_map, commandBuffer)->CmdDispatch(commandBuffer, x, y, z);
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdDispatchIndirect(my_data->report_data, buffer, offset);
+    skip_call |= parameter_validation_vkCmdDispatchIndirect(my_data->report_data, buffer, offset);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdDispatchIndirect(commandBuffer, buffer, offset);
     }
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
                                          uint32_t regionCount, const VkBufferCopy *pRegions) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdCopyBuffer(my_data->report_data, srcBuffer, dstBuffer, regionCount, pRegions);
+    skip_call |= parameter_validation_vkCmdCopyBuffer(my_data->report_data, srcBuffer, dstBuffer, regionCount, pRegions);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
     }
@@ -3813,14 +4114,14 @@
         if ((pRegions->srcSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT |
                                                     VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    UNRECOGNIZED_VALUE, "PARAMCHECK",
+                    UNRECOGNIZED_VALUE, LayerName,
                     "vkCmdCopyImage parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator");
             return false;
         }
         if ((pRegions->dstSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT |
                                                     VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    UNRECOGNIZED_VALUE, "PARAMCHECK",
+                    UNRECOGNIZED_VALUE, LayerName,
                     "vkCmdCopyImage parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator");
             return false;
         }
@@ -3829,17 +4130,17 @@
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
-             VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy *pRegions) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+                                        VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
+                                        const VkImageCopy *pRegions) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |=
-        parameter_validation_vkCmdCopyImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+    skip_call |= parameter_validation_vkCmdCopyImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout,
+                                                     regionCount, pRegions);
 
-    if (!skipCall) {
+    if (!skip_call) {
         PreCmdCopyImage(commandBuffer, pRegions);
 
         get_dispatch_table(pc_device_table_map, commandBuffer)
@@ -3852,14 +4153,14 @@
         if ((pRegions->srcSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT |
                                                     VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    UNRECOGNIZED_VALUE, "PARAMCHECK",
+                    UNRECOGNIZED_VALUE, LayerName,
                     "vkCmdCopyImage parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator");
             return false;
         }
         if ((pRegions->dstSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT |
                                                     VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    UNRECOGNIZED_VALUE, "PARAMCHECK",
+                    UNRECOGNIZED_VALUE, LayerName,
                     "vkCmdCopyImage parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator");
             return false;
         }
@@ -3868,17 +4169,17 @@
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
-             VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+                                        VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
+                                        const VkImageBlit *pRegions, VkFilter filter) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdBlitImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
-                                           pRegions, filter);
+    skip_call |= parameter_validation_vkCmdBlitImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout,
+                                                     regionCount, pRegions, filter);
 
-    if (!skipCall) {
+    if (!skip_call) {
         PreCmdBlitImage(commandBuffer, pRegions);
 
         get_dispatch_table(pc_device_table_map, commandBuffer)
@@ -3891,7 +4192,7 @@
         if ((pRegions->imageSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT |
                                                       VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    UNRECOGNIZED_VALUE, "PARAMCHECK",
+                    UNRECOGNIZED_VALUE, LayerName,
                     "vkCmdCopyBufferToImage parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an unrecognized "
                     "enumerator");
             return false;
@@ -3901,17 +4202,17 @@
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
-                                                VkImage dstImage, VkImageLayout dstImageLayout,
-                                                uint32_t regionCount, const VkBufferImageCopy *pRegions) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
+                                                VkImageLayout dstImageLayout, uint32_t regionCount,
+                                                const VkBufferImageCopy *pRegions) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |=
-        parameter_validation_vkCmdCopyBufferToImage(my_data->report_data, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
+    skip_call |= parameter_validation_vkCmdCopyBufferToImage(my_data->report_data, srcBuffer, dstImage, dstImageLayout, regionCount,
+                                                             pRegions);
 
-    if (!skipCall) {
+    if (!skip_call) {
         PreCmdCopyBufferToImage(commandBuffer, pRegions);
 
         get_dispatch_table(pc_device_table_map, commandBuffer)
@@ -3924,7 +4225,7 @@
         if ((pRegions->imageSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT |
                                                       VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    UNRECOGNIZED_VALUE, "PARAMCHECK",
+                    UNRECOGNIZED_VALUE, LayerName,
                     "vkCmdCopyImageToBuffer parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an unrecognized "
                     "enumerator");
             return false;
@@ -3934,17 +4235,16 @@
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
-                                                VkImageLayout srcImageLayout, VkBuffer dstBuffer,
-                                                uint32_t regionCount, const VkBufferImageCopy *pRegions) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+                                                VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |=
-        parameter_validation_vkCmdCopyImageToBuffer(my_data->report_data, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
+    skip_call |= parameter_validation_vkCmdCopyImageToBuffer(my_data->report_data, srcImage, srcImageLayout, dstBuffer, regionCount,
+                                                             pRegions);
 
-    if (!skipCall) {
+    if (!skip_call) {
         PreCmdCopyImageToBuffer(commandBuffer, pRegions);
 
         get_dispatch_table(pc_device_table_map, commandBuffer)
@@ -3952,60 +4252,94 @@
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
-                                           VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t *pData) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
+                                           VkDeviceSize dataSize, const uint32_t *pData) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdUpdateBuffer(my_data->report_data, dstBuffer, dstOffset, dataSize, pData);
+    skip_call |= parameter_validation_vkCmdUpdateBuffer(my_data->report_data, dstBuffer, dstOffset, dataSize, pData);
 
-    if (!skipCall) {
+    if (dstOffset & 3) {
+        skip_call |= log_msg(
+            my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE,
+            LayerName, "CmdUpdateBuffer parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4", dstOffset);
+    }
+
+    if ((dataSize <= 0) || (dataSize > 65536)) {
+        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
+                             INVALID_USAGE, LayerName, "CmdUpdateBuffer parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64
+                                                       "), must be greater than zero and less than or equal to 65536",
+                             dataSize);
+    } else if (dataSize & 3) {
+        skip_call |= log_msg(
+            my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE,
+            LayerName, "CmdUpdateBuffer parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64 "), is not a multiple of 4", dataSize);
+    }
+
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
+                                         VkDeviceSize size, uint32_t data) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdFillBuffer(my_data->report_data, dstBuffer, dstOffset, size, data);
+    skip_call |= parameter_validation_vkCmdFillBuffer(my_data->report_data, dstBuffer, dstOffset, size, data);
 
-    if (!skipCall) {
+    if (dstOffset & 3) {
+        skip_call |= log_msg(
+            my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE,
+            LayerName, "vkCmdFillBuffer parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4", dstOffset);
+    }
+
+    if (size != VK_WHOLE_SIZE) {
+        if (size <= 0) {
+            skip_call |= log_msg(
+                my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE,
+                LayerName, "vkCmdFillBuffer parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), must be greater than zero", size);
+        } else if (size & 3) {
+            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
+                                 INVALID_USAGE, LayerName,
+                                 "vkCmdFillBuffer parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), is not a multiple of 4", size);
+        }
+    }
+
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
-                                              VkImageLayout imageLayout, const VkClearColorValue *pColor,
-                                              uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
+                                              const VkClearColorValue *pColor, uint32_t rangeCount,
+                                              const VkImageSubresourceRange *pRanges) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdClearColorImage(my_data->report_data, image, imageLayout, pColor, rangeCount, pRanges);
+    skip_call |= parameter_validation_vkCmdClearColorImage(my_data->report_data, image, imageLayout, pColor, rangeCount, pRanges);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
-                          const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
-                          const VkImageSubresourceRange *pRanges) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout,
+                                                     const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount,
+                                                     const VkImageSubresourceRange *pRanges) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |=
-        parameter_validation_vkCmdClearDepthStencilImage(my_data->report_data, image, imageLayout, pDepthStencil, rangeCount, pRanges);
+    skip_call |= parameter_validation_vkCmdClearDepthStencilImage(my_data->report_data, image, imageLayout, pDepthStencil,
+                                                                  rangeCount, pRanges);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
     }
@@ -4014,13 +4348,13 @@
 VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
                                                const VkClearAttachment *pAttachments, uint32_t rectCount,
                                                const VkClearRect *pRects) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdClearAttachments(my_data->report_data, attachmentCount, pAttachments, rectCount, pRects);
+    skip_call |= parameter_validation_vkCmdClearAttachments(my_data->report_data, attachmentCount, pAttachments, rectCount, pRects);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
     }
@@ -4032,7 +4366,7 @@
                                                     VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(
                 mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                UNRECOGNIZED_VALUE, "PARAMCHECK",
+                UNRECOGNIZED_VALUE, LayerName,
                 "vkCmdResolveImage parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator");
             return false;
         }
@@ -4040,7 +4374,7 @@
                                                     VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) {
             log_msg(
                 mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                UNRECOGNIZED_VALUE, "PARAMCHECK",
+                UNRECOGNIZED_VALUE, LayerName,
                 "vkCmdResolveImage parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator");
             return false;
         }
@@ -4049,17 +4383,17 @@
     return true;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage,
-                VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
+                                           VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
+                                           const VkImageResolve *pRegions) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdResolveImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
-                                              pRegions);
+    skip_call |= parameter_validation_vkCmdResolveImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout,
+                                                        regionCount, pRegions);
 
-    if (!skipCall) {
+    if (!skip_call) {
         PreCmdResolveImage(commandBuffer, pRegions);
 
         get_dispatch_table(pc_device_table_map, commandBuffer)
@@ -4067,106 +4401,104 @@
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdSetEvent(my_data->report_data, event, stageMask);
+    skip_call |= parameter_validation_vkCmdSetEvent(my_data->report_data, event, stageMask);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetEvent(commandBuffer, event, stageMask);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdResetEvent(my_data->report_data, event, stageMask);
+    skip_call |= parameter_validation_vkCmdResetEvent(my_data->report_data, event, stageMask);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdResetEvent(commandBuffer, event, stageMask);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, VkPipelineStageFlags srcStageMask,
-              VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
-              uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
-              uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
+                                         VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
+                                         uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
+                                         uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
+                                         uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdWaitEvents(my_data->report_data, eventCount, pEvents, srcStageMask, dstStageMask,
-                                            memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
-                                            imageMemoryBarrierCount, pImageMemoryBarriers);
+    skip_call |= parameter_validation_vkCmdWaitEvents(my_data->report_data, eventCount, pEvents, srcStageMask, dstStageMask,
+                                                      memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
+                                                      pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers,
                             bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
-                   VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
-                   uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
-                   uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
+                                              VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
+                                              uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
+                                              uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers,
+                                              uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdPipelineBarrier(my_data->report_data, srcStageMask, dstStageMask, dependencyFlags,
-                                                 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
-                                                 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+    skip_call |= parameter_validation_vkCmdPipelineBarrier(my_data->report_data, srcStageMask, dstStageMask, dependencyFlags,
+                                                           memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
+                                                           pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers,
                                  bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot, VkQueryControlFlags flags) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot,
+                                         VkQueryControlFlags flags) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdBeginQuery(my_data->report_data, queryPool, slot, flags);
+    skip_call |= parameter_validation_vkCmdBeginQuery(my_data->report_data, queryPool, slot, flags);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdBeginQuery(commandBuffer, queryPool, slot, flags);
     }
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdEndQuery(my_data->report_data, queryPool, slot);
+    skip_call |= parameter_validation_vkCmdEndQuery(my_data->report_data, queryPool, slot);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdEndQuery(commandBuffer, queryPool, slot);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery,
+                                             uint32_t queryCount) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdResetQueryPool(my_data->report_data, queryPool, firstQuery, queryCount);
+    skip_call |= parameter_validation_vkCmdResetQueryPool(my_data->report_data, queryPool, firstQuery, queryCount);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
     }
 }
@@ -4181,71 +4513,70 @@
 
 VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
                                              VkQueryPool queryPool, uint32_t query) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdWriteTimestamp(my_data->report_data, pipelineStage, queryPool, query);
+    skip_call |= parameter_validation_vkCmdWriteTimestamp(my_data->report_data, pipelineStage, queryPool, query);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query);
 
         PostCmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount,
-                        VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery,
+                                                   uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset,
+                                                   VkDeviceSize stride, VkQueryResultFlags flags) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdCopyQueryPoolResults(my_data->report_data, queryPool, firstQuery, queryCount, dstBuffer,
-                                                               dstOffset, stride, flags);
+    skip_call |= parameter_validation_vkCmdCopyQueryPoolResults(my_data->report_data, queryPool, firstQuery, queryCount, dstBuffer,
+                                                                dstOffset, stride, flags);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
-                                            VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
-                                            const void *pValues) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags,
+                                            uint32_t offset, uint32_t size, const void *pValues) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdPushConstants(my_data->report_data, layout, stageFlags, offset, size, pValues);
+    skip_call |= parameter_validation_vkCmdPushConstants(my_data->report_data, layout, stageFlags, offset, size, pValues);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
     }
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin,
+                                              VkSubpassContents contents) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdBeginRenderPass(my_data->report_data, pRenderPassBegin, contents);
+    skip_call |= parameter_validation_vkCmdBeginRenderPass(my_data->report_data, pRenderPassBegin, contents);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
     }
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
-    bool skipCall = false;
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdNextSubpass(my_data->report_data, contents);
+    skip_call |= parameter_validation_vkCmdNextSubpass(my_data->report_data, contents);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)->CmdNextSubpass(commandBuffer, contents);
     }
 }
@@ -4254,23 +4585,39 @@
     get_dispatch_table(pc_device_table_map, commandBuffer)->CmdEndRenderPass(commandBuffer);
 }
 
-VKAPI_ATTR void VKAPI_CALL
-CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) {
-    bool skipCall = false;
+VKAPI_ATTR void VKAPI_CALL CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
+                                              const VkCommandBuffer *pCommandBuffers) {
+    bool skip_call = false;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     assert(my_data != NULL);
 
-    skipCall |= parameter_validation_vkCmdExecuteCommands(my_data->report_data, commandBufferCount, pCommandBuffers);
+    skip_call |= parameter_validation_vkCmdExecuteCommands(my_data->report_data, commandBufferCount, pCommandBuffers);
 
-    if (!skipCall) {
+    if (!skip_call) {
         get_dispatch_table(pc_device_table_map, commandBuffer)
             ->CmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers);
     }
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
-                                                                  const char *pLayerName, uint32_t *pCount,
-                                                                  VkExtensionProperties *pProperties) {
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
+                                                              VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
+                                                                    VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, global_layer.layerName))
+        return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
+
+    return VK_ERROR_LAYER_NOT_PRESENT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
+                                                                  uint32_t *pCount, VkExtensionProperties *pProperties) {
     /* parameter_validation does not have any physical device extensions */
     if (pLayerName && !strcmp(pLayerName, global_layer.layerName))
         return util_GetExtensionProperties(0, NULL, pCount, pProperties);
@@ -4281,11 +4628,367 @@
         ->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
 }
 
-static PFN_vkVoidFunction
-intercept_core_instance_command(const char *name);
+// WSI Extension Functions
 
-static PFN_vkVoidFunction
-intercept_core_device_command(const char *name);
+VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+                                                  const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkCreateSwapchainKHR(my_data->report_data, pCreateInfo, pAllocator, pSwapchain);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_device_table_map, device)->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+
+        validate_result(my_data->report_data, "vkCreateSwapchainKHR", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
+                                                     VkImage *pSwapchainImages) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |=
+        parameter_validation_vkGetSwapchainImagesKHR(my_data->report_data, swapchain, pSwapchainImageCount, pSwapchainImages);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_device_table_map, device)
+                     ->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
+
+        validate_result(my_data->report_data, "vkGetSwapchainImagesKHR", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
+                                                   VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |=
+        parameter_validation_vkAcquireNextImageKHR(my_data->report_data, swapchain, timeout, semaphore, fence, pImageIndex);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_device_table_map, device)
+                     ->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+
+        validate_result(my_data->report_data, "vkAcquireNextImageKHR", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkQueuePresentKHR(my_data->report_data, pPresentInfo);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_device_table_map, queue)->QueuePresentKHR(queue, pPresentInfo);
+
+        validate_result(my_data->report_data, "vkQueuePresentKHR", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
+                                                                  VkSurfaceKHR surface, VkBool32 *pSupported) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |=
+        parameter_validation_vkGetPhysicalDeviceSurfaceSupportKHR(my_data->report_data, queueFamilyIndex, surface, pSupported);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported);
+
+        validate_result(my_data->report_data, "vkGetPhysicalDeviceSurfaceSupportKHR", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+                                                                       VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |=
+        parameter_validation_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(my_data->report_data, surface, pSurfaceCapabilities);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities);
+
+        validate_result(my_data->report_data, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+                                                                  uint32_t *pSurfaceFormatCount,
+                                                                  VkSurfaceFormatKHR *pSurfaceFormats) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkGetPhysicalDeviceSurfaceFormatsKHR(my_data->report_data, surface, pSurfaceFormatCount,
+                                                                           pSurfaceFormats);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
+
+        validate_result(my_data->report_data, "vkGetPhysicalDeviceSurfaceFormatsKHR", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+                                                                       uint32_t *pPresentModeCount,
+                                                                       VkPresentModeKHR *pPresentModes) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkGetPhysicalDeviceSurfacePresentModesKHR(my_data->report_data, surface, pPresentModeCount,
+                                                                                pPresentModes);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, pPresentModes);
+
+        validate_result(my_data->report_data, "vkGetPhysicalDeviceSurfacePresentModesKHR", result);
+    }
+
+    return result;
+}
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+                                                     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call = parameter_validation_vkCreateWin32SurfaceKHR(my_data->report_data, pCreateInfo, pAllocator, pSurface);
+
+    if (!skip_call) {
+        result =
+            get_dispatch_table(pc_instance_table_map, instance)->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    }
+
+    validate_result(my_data->report_data, "vkCreateWin32SurfaceKHR", result);
+
+    return result;
+}
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call = parameter_validation_vkCreateXcbSurfaceKHR(my_data->report_data, pCreateInfo, pAllocator, pSurface);
+
+    if (!skip_call) {
+        result =
+            get_dispatch_table(pc_instance_table_map, instance)->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    }
+
+    validate_result(my_data->report_data, "vkCreateXcbSurfaceKHR", result);
+
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                          uint32_t queueFamilyIndex, xcb_connection_t *connection,
+                                                                          xcb_visualid_t visual_id) {
+    VkBool32 result = false;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call = parameter_validation_vkGetPhysicalDeviceXcbPresentationSupportKHR(my_data->report_data, queueFamilyIndex,
+                                                                                       connection, visual_id);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection, visual_id);
+    }
+
+    return result;
+}
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
+                                                    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call = parameter_validation_vkCreateXlibSurfaceKHR(my_data->report_data, pCreateInfo, pAllocator, pSurface);
+
+    if (!skip_call) {
+        result =
+            get_dispatch_table(pc_instance_table_map, instance)->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    }
+
+    validate_result(my_data->report_data, "vkCreateXlibSurfaceKHR", result);
+
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                           uint32_t queueFamilyIndex, Display *dpy,
+                                                                           VisualID visualID) {
+    VkBool32 result = false;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call =
+        parameter_validation_vkGetPhysicalDeviceXlibPresentationSupportKHR(my_data->report_data, queueFamilyIndex, dpy, visualID);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, dpy, visualID);
+    }
+}
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call = parameter_validation_vkCreateMirSurfaceKHR(my_data->report_data, pCreateInfo, pAllocator, pSurface);
+
+    if (!skip_call) {
+        result =
+            get_dispatch_table(pc_instance_table_map, instance)->CreateMirSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    }
+
+    validate_result(my_data->report_data, "vkCreateMirSurfaceKHR", result);
+
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                          uint32_t queueFamilyIndex, MirConnection *connection) {
+    VkBool32 result = false;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call =
+        parameter_validation_vkGetPhysicalDeviceMirPresentationSupportKHR(my_data->report_data, queueFamilyIndex, connection);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceMirPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection);
+    }
+}
+#endif // VK_USE_PLATFORM_MIR_KHR
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
+                                                       const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call = parameter_validation_vkCreateWaylandSurfaceKHR(my_data->report_data, pCreateInfo, pAllocator, pSurface);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, instance)
+                     ->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    }
+
+    validate_result(my_data->report_data, "vkCreateWaylandSurfaceKHR", result);
+
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+                                                                              uint32_t queueFamilyIndex,
+                                                                              struct wl_display *display) {
+    VkBool32 result = false;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call =
+        parameter_validation_vkGetPhysicalDeviceWaylandPresentationSupportKHR(my_data->report_data, queueFamilyIndex, display);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, display);
+    }
+}
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
+                                                       const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    assert(my_data != NULL);
+
+    bool skip_call = parameter_validation_vkCreateAndroidSurfaceKHR(my_data->report_data, pCreateInfo, pAllocator, pSurface);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, instance)
+                     ->CreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+    }
+
+    validate_result(my_data->report_data, "vkCreateAndroidSurfaceKHR", result);
+
+    return result;
+}
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+static PFN_vkVoidFunction intercept_core_instance_command(const char *name);
+
+static PFN_vkVoidFunction intercept_core_device_command(const char *name);
+
+static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkDevice device);
+
+static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkInstance instance);
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
     assert(device);
@@ -4300,6 +5003,10 @@
     if (proc)
         return proc;
 
+    proc = InterceptWsiEnabledCommand(funcName, device);
+    if (proc)
+        return proc;
+
     if (get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr == NULL)
         return NULL;
     return get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr(device, funcName);
@@ -4309,6 +5016,10 @@
     PFN_vkVoidFunction proc = intercept_core_instance_command(funcName);
     if (!proc)
         proc = intercept_core_device_command(funcName);
+
+    if (!proc)
+        proc = InterceptWsiEnabledCommand(funcName, VkDevice(VK_NULL_HANDLE));
+
     if (proc)
         return proc;
 
@@ -4317,6 +5028,9 @@
     layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
 
     proc = debug_report_get_instance_proc_addr(data->report_data, funcName);
+    if (!proc)
+        proc = InterceptWsiEnabledCommand(funcName, instance);
+
     if (proc)
         return proc;
 
@@ -4325,32 +5039,30 @@
     return get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
 }
 
-static PFN_vkVoidFunction
-intercept_core_instance_command(const char *name) {
+static PFN_vkVoidFunction intercept_core_instance_command(const char *name) {
     static const struct {
         const char *name;
         PFN_vkVoidFunction proc;
     } core_instance_commands[] = {
-        { "vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr) },
-        { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) },
-        { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) },
-        { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) },
-        { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) },
-        { "vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties) },
-        { "vkGetPhysicalDeviceFeatures", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFeatures) },
-        { "vkGetPhysicalDeviceFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFormatProperties) },
-        { "vkGetPhysicalDeviceImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceImageFormatProperties) },
-        { "vkGetPhysicalDeviceSparseImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSparseImageFormatProperties) },
-        { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) },
-        { "vkGetPhysicalDeviceMemoryProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMemoryProperties) },
-        { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) },
+        {"vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr)},
+        {"vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance)},
+        {"vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance)},
+        {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice)},
+        {"vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices)},
+        {"vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties)},
+        {"vkGetPhysicalDeviceFeatures", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFeatures)},
+        {"vkGetPhysicalDeviceFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFormatProperties)},
+        {"vkGetPhysicalDeviceImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceImageFormatProperties)},
+        {"vkGetPhysicalDeviceSparseImageFormatProperties",
+         reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSparseImageFormatProperties)},
+        {"vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties)},
+        {"vkGetPhysicalDeviceMemoryProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMemoryProperties)},
+        {"vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties)},
+        {"vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties)},
+        {"vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties)},
+        {"vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties)},
     };
 
-    // we should never be queried for these commands
-    assert(strcmp(name, "vkEnumerateInstanceLayerProperties") &&
-           strcmp(name, "vkEnumerateInstanceExtensionProperties") &&
-           strcmp(name, "vkEnumerateDeviceLayerProperties"));
-
     for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
         if (!strcmp(core_instance_commands[i].name, name))
             return core_instance_commands[i].proc;
@@ -4359,124 +5071,128 @@
     return nullptr;
 }
 
-static PFN_vkVoidFunction
-intercept_core_device_command(const char *name) {
+static PFN_vkVoidFunction intercept_core_device_command(const char *name) {
     static const struct {
         const char *name;
         PFN_vkVoidFunction proc;
     } core_device_commands[] = {
-        { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) },
-        { "vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice) },
-        { "vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue) },
-        { "vkQueueSubmit", reinterpret_cast<PFN_vkVoidFunction>(QueueSubmit) },
-        { "vkQueueWaitIdle", reinterpret_cast<PFN_vkVoidFunction>(QueueWaitIdle) },
-        { "vkDeviceWaitIdle", reinterpret_cast<PFN_vkVoidFunction>(DeviceWaitIdle) },
-        { "vkAllocateMemory", reinterpret_cast<PFN_vkVoidFunction>(AllocateMemory) },
-        { "vkFreeMemory", reinterpret_cast<PFN_vkVoidFunction>(FreeMemory) },
-        { "vkMapMemory", reinterpret_cast<PFN_vkVoidFunction>(MapMemory) },
-        { "vkUnmapMemory", reinterpret_cast<PFN_vkVoidFunction>(UnmapMemory) },
-        { "vkFlushMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(FlushMappedMemoryRanges) },
-        { "vkInvalidateMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(InvalidateMappedMemoryRanges) },
-        { "vkGetDeviceMemoryCommitment", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceMemoryCommitment) },
-        { "vkBindBufferMemory", reinterpret_cast<PFN_vkVoidFunction>(BindBufferMemory) },
-        { "vkBindImageMemory", reinterpret_cast<PFN_vkVoidFunction>(BindImageMemory) },
-        { "vkCreateFence", reinterpret_cast<PFN_vkVoidFunction>(CreateFence) },
-        { "vkDestroyFence", reinterpret_cast<PFN_vkVoidFunction>(DestroyFence) },
-        { "vkResetFences", reinterpret_cast<PFN_vkVoidFunction>(ResetFences) },
-        { "vkGetFenceStatus", reinterpret_cast<PFN_vkVoidFunction>(GetFenceStatus) },
-        { "vkWaitForFences", reinterpret_cast<PFN_vkVoidFunction>(WaitForFences) },
-        { "vkCreateSemaphore", reinterpret_cast<PFN_vkVoidFunction>(CreateSemaphore) },
-        { "vkDestroySemaphore", reinterpret_cast<PFN_vkVoidFunction>(DestroySemaphore) },
-        { "vkCreateEvent", reinterpret_cast<PFN_vkVoidFunction>(CreateEvent) },
-        { "vkDestroyEvent", reinterpret_cast<PFN_vkVoidFunction>(DestroyEvent) },
-        { "vkGetEventStatus", reinterpret_cast<PFN_vkVoidFunction>(GetEventStatus) },
-        { "vkSetEvent", reinterpret_cast<PFN_vkVoidFunction>(SetEvent) },
-        { "vkResetEvent", reinterpret_cast<PFN_vkVoidFunction>(ResetEvent) },
-        { "vkCreateQueryPool", reinterpret_cast<PFN_vkVoidFunction>(CreateQueryPool) },
-        { "vkDestroyQueryPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyQueryPool) },
-        { "vkGetQueryPoolResults", reinterpret_cast<PFN_vkVoidFunction>(GetQueryPoolResults) },
-        { "vkCreateBuffer", reinterpret_cast<PFN_vkVoidFunction>(CreateBuffer) },
-        { "vkDestroyBuffer", reinterpret_cast<PFN_vkVoidFunction>(DestroyBuffer) },
-        { "vkCreateBufferView", reinterpret_cast<PFN_vkVoidFunction>(CreateBufferView) },
-        { "vkDestroyBufferView", reinterpret_cast<PFN_vkVoidFunction>(DestroyBufferView) },
-        { "vkCreateImage", reinterpret_cast<PFN_vkVoidFunction>(CreateImage) },
-        { "vkDestroyImage", reinterpret_cast<PFN_vkVoidFunction>(DestroyImage) },
-        { "vkGetImageSubresourceLayout", reinterpret_cast<PFN_vkVoidFunction>(GetImageSubresourceLayout) },
-        { "vkCreateImageView", reinterpret_cast<PFN_vkVoidFunction>(CreateImageView) },
-        { "vkDestroyImageView", reinterpret_cast<PFN_vkVoidFunction>(DestroyImageView) },
-        { "vkCreateShaderModule", reinterpret_cast<PFN_vkVoidFunction>(CreateShaderModule) },
-        { "vkDestroyShaderModule", reinterpret_cast<PFN_vkVoidFunction>(DestroyShaderModule) },
-        { "vkCreatePipelineCache", reinterpret_cast<PFN_vkVoidFunction>(CreatePipelineCache) },
-        { "vkDestroyPipelineCache", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipelineCache) },
-        { "vkGetPipelineCacheData", reinterpret_cast<PFN_vkVoidFunction>(GetPipelineCacheData) },
-        { "vkMergePipelineCaches", reinterpret_cast<PFN_vkVoidFunction>(MergePipelineCaches) },
-        { "vkCreateGraphicsPipelines", reinterpret_cast<PFN_vkVoidFunction>(CreateGraphicsPipelines) },
-        { "vkCreateComputePipelines", reinterpret_cast<PFN_vkVoidFunction>(CreateComputePipelines) },
-        { "vkDestroyPipeline", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipeline) },
-        { "vkCreatePipelineLayout", reinterpret_cast<PFN_vkVoidFunction>(CreatePipelineLayout) },
-        { "vkDestroyPipelineLayout", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipelineLayout) },
-        { "vkCreateSampler", reinterpret_cast<PFN_vkVoidFunction>(CreateSampler) },
-        { "vkDestroySampler", reinterpret_cast<PFN_vkVoidFunction>(DestroySampler) },
-        { "vkCreateDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(CreateDescriptorSetLayout) },
-        { "vkDestroyDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(DestroyDescriptorSetLayout) },
-        { "vkCreateDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(CreateDescriptorPool) },
-        { "vkDestroyDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyDescriptorPool) },
-        { "vkResetDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(ResetDescriptorPool) },
-        { "vkAllocateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(AllocateDescriptorSets) },
-        { "vkFreeDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(FreeDescriptorSets) },
-        { "vkUpdateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(UpdateDescriptorSets) },
-        { "vkCmdSetViewport", reinterpret_cast<PFN_vkVoidFunction>(CmdSetViewport) },
-        { "vkCmdSetScissor", reinterpret_cast<PFN_vkVoidFunction>(CmdSetScissor) },
-        { "vkCmdSetLineWidth", reinterpret_cast<PFN_vkVoidFunction>(CmdSetLineWidth) },
-        { "vkCmdSetDepthBias", reinterpret_cast<PFN_vkVoidFunction>(CmdSetDepthBias) },
-        { "vkCmdSetBlendConstants", reinterpret_cast<PFN_vkVoidFunction>(CmdSetBlendConstants) },
-        { "vkCmdSetDepthBounds", reinterpret_cast<PFN_vkVoidFunction>(CmdSetDepthBounds) },
-        { "vkCmdSetStencilCompareMask", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilCompareMask) },
-        { "vkCmdSetStencilWriteMask", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilWriteMask) },
-        { "vkCmdSetStencilReference", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilReference) },
-        { "vkAllocateCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers) },
-        { "vkFreeCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(FreeCommandBuffers) },
-        { "vkBeginCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(BeginCommandBuffer) },
-        { "vkEndCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(EndCommandBuffer) },
-        { "vkResetCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(ResetCommandBuffer) },
-        { "vkCmdBindPipeline", reinterpret_cast<PFN_vkVoidFunction>(CmdBindPipeline) },
-        { "vkCmdBindDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(CmdBindDescriptorSets) },
-        { "vkCmdBindVertexBuffers", reinterpret_cast<PFN_vkVoidFunction>(CmdBindVertexBuffers) },
-        { "vkCmdBindIndexBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdBindIndexBuffer) },
-        { "vkCmdDraw", reinterpret_cast<PFN_vkVoidFunction>(CmdDraw) },
-        { "vkCmdDrawIndexed", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndexed) },
-        { "vkCmdDrawIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndirect) },
-        { "vkCmdDrawIndexedIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndexedIndirect) },
-        { "vkCmdDispatch", reinterpret_cast<PFN_vkVoidFunction>(CmdDispatch) },
-        { "vkCmdDispatchIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDispatchIndirect) },
-        { "vkCmdCopyBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyBuffer) },
-        { "vkCmdCopyImage", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyImage) },
-        { "vkCmdBlitImage", reinterpret_cast<PFN_vkVoidFunction>(CmdBlitImage) },
-        { "vkCmdCopyBufferToImage", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyBufferToImage) },
-        { "vkCmdCopyImageToBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyImageToBuffer) },
-        { "vkCmdUpdateBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdUpdateBuffer) },
-        { "vkCmdFillBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdFillBuffer) },
-        { "vkCmdClearColorImage", reinterpret_cast<PFN_vkVoidFunction>(CmdClearColorImage) },
-        { "vkCmdResolveImage", reinterpret_cast<PFN_vkVoidFunction>(CmdResolveImage) },
-        { "vkCmdSetEvent", reinterpret_cast<PFN_vkVoidFunction>(CmdSetEvent) },
-        { "vkCmdResetEvent", reinterpret_cast<PFN_vkVoidFunction>(CmdResetEvent) },
-        { "vkCmdWaitEvents", reinterpret_cast<PFN_vkVoidFunction>(CmdWaitEvents) },
-        { "vkCmdPipelineBarrier", reinterpret_cast<PFN_vkVoidFunction>(CmdPipelineBarrier) },
-        { "vkCmdBeginQuery", reinterpret_cast<PFN_vkVoidFunction>(CmdBeginQuery) },
-        { "vkCmdEndQuery", reinterpret_cast<PFN_vkVoidFunction>(CmdEndQuery) },
-        { "vkCmdResetQueryPool", reinterpret_cast<PFN_vkVoidFunction>(CmdResetQueryPool) },
-        { "vkCmdWriteTimestamp", reinterpret_cast<PFN_vkVoidFunction>(CmdWriteTimestamp) },
-        { "vkCmdCopyQueryPoolResults", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyQueryPoolResults) },
-        { "vkCreateFramebuffer", reinterpret_cast<PFN_vkVoidFunction>(CreateFramebuffer) },
-        { "vkDestroyFramebuffer", reinterpret_cast<PFN_vkVoidFunction>(DestroyFramebuffer) },
-        { "vkCreateRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CreateRenderPass) },
-        { "vkDestroyRenderPass", reinterpret_cast<PFN_vkVoidFunction>(DestroyRenderPass) },
-        { "vkGetRenderAreaGranularity", reinterpret_cast<PFN_vkVoidFunction>(GetRenderAreaGranularity) },
-        { "vkCreateCommandPool", reinterpret_cast<PFN_vkVoidFunction>(CreateCommandPool) },
-        { "vkDestroyCommandPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyCommandPool) },
-        { "vkResetCommandPool", reinterpret_cast<PFN_vkVoidFunction>(ResetCommandPool) },
-        { "vkCmdBeginRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CmdBeginRenderPass) },
-        { "vkCmdNextSubpass", reinterpret_cast<PFN_vkVoidFunction>(CmdNextSubpass) },
+        {"vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr)},
+        {"vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice)},
+        {"vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue)},
+        {"vkQueueSubmit", reinterpret_cast<PFN_vkVoidFunction>(QueueSubmit)},
+        {"vkQueueWaitIdle", reinterpret_cast<PFN_vkVoidFunction>(QueueWaitIdle)},
+        {"vkDeviceWaitIdle", reinterpret_cast<PFN_vkVoidFunction>(DeviceWaitIdle)},
+        {"vkAllocateMemory", reinterpret_cast<PFN_vkVoidFunction>(AllocateMemory)},
+        {"vkFreeMemory", reinterpret_cast<PFN_vkVoidFunction>(FreeMemory)},
+        {"vkMapMemory", reinterpret_cast<PFN_vkVoidFunction>(MapMemory)},
+        {"vkUnmapMemory", reinterpret_cast<PFN_vkVoidFunction>(UnmapMemory)},
+        {"vkFlushMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(FlushMappedMemoryRanges)},
+        {"vkInvalidateMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(InvalidateMappedMemoryRanges)},
+        {"vkGetDeviceMemoryCommitment", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceMemoryCommitment)},
+        {"vkBindBufferMemory", reinterpret_cast<PFN_vkVoidFunction>(BindBufferMemory)},
+        {"vkBindImageMemory", reinterpret_cast<PFN_vkVoidFunction>(BindImageMemory)},
+        {"vkCreateFence", reinterpret_cast<PFN_vkVoidFunction>(CreateFence)},
+        {"vkDestroyFence", reinterpret_cast<PFN_vkVoidFunction>(DestroyFence)},
+        {"vkResetFences", reinterpret_cast<PFN_vkVoidFunction>(ResetFences)},
+        {"vkGetFenceStatus", reinterpret_cast<PFN_vkVoidFunction>(GetFenceStatus)},
+        {"vkWaitForFences", reinterpret_cast<PFN_vkVoidFunction>(WaitForFences)},
+        {"vkCreateSemaphore", reinterpret_cast<PFN_vkVoidFunction>(CreateSemaphore)},
+        {"vkDestroySemaphore", reinterpret_cast<PFN_vkVoidFunction>(DestroySemaphore)},
+        {"vkCreateEvent", reinterpret_cast<PFN_vkVoidFunction>(CreateEvent)},
+        {"vkDestroyEvent", reinterpret_cast<PFN_vkVoidFunction>(DestroyEvent)},
+        {"vkGetEventStatus", reinterpret_cast<PFN_vkVoidFunction>(GetEventStatus)},
+        {"vkSetEvent", reinterpret_cast<PFN_vkVoidFunction>(SetEvent)},
+        {"vkResetEvent", reinterpret_cast<PFN_vkVoidFunction>(ResetEvent)},
+        {"vkCreateQueryPool", reinterpret_cast<PFN_vkVoidFunction>(CreateQueryPool)},
+        {"vkDestroyQueryPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyQueryPool)},
+        {"vkGetQueryPoolResults", reinterpret_cast<PFN_vkVoidFunction>(GetQueryPoolResults)},
+        {"vkCreateBuffer", reinterpret_cast<PFN_vkVoidFunction>(CreateBuffer)},
+        {"vkDestroyBuffer", reinterpret_cast<PFN_vkVoidFunction>(DestroyBuffer)},
+        {"vkCreateBufferView", reinterpret_cast<PFN_vkVoidFunction>(CreateBufferView)},
+        {"vkDestroyBufferView", reinterpret_cast<PFN_vkVoidFunction>(DestroyBufferView)},
+        {"vkCreateImage", reinterpret_cast<PFN_vkVoidFunction>(CreateImage)},
+        {"vkDestroyImage", reinterpret_cast<PFN_vkVoidFunction>(DestroyImage)},
+        {"vkGetImageSubresourceLayout", reinterpret_cast<PFN_vkVoidFunction>(GetImageSubresourceLayout)},
+        {"vkCreateImageView", reinterpret_cast<PFN_vkVoidFunction>(CreateImageView)},
+        {"vkDestroyImageView", reinterpret_cast<PFN_vkVoidFunction>(DestroyImageView)},
+        {"vkCreateShaderModule", reinterpret_cast<PFN_vkVoidFunction>(CreateShaderModule)},
+        {"vkDestroyShaderModule", reinterpret_cast<PFN_vkVoidFunction>(DestroyShaderModule)},
+        {"vkCreatePipelineCache", reinterpret_cast<PFN_vkVoidFunction>(CreatePipelineCache)},
+        {"vkDestroyPipelineCache", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipelineCache)},
+        {"vkGetPipelineCacheData", reinterpret_cast<PFN_vkVoidFunction>(GetPipelineCacheData)},
+        {"vkMergePipelineCaches", reinterpret_cast<PFN_vkVoidFunction>(MergePipelineCaches)},
+        {"vkCreateGraphicsPipelines", reinterpret_cast<PFN_vkVoidFunction>(CreateGraphicsPipelines)},
+        {"vkCreateComputePipelines", reinterpret_cast<PFN_vkVoidFunction>(CreateComputePipelines)},
+        {"vkDestroyPipeline", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipeline)},
+        {"vkCreatePipelineLayout", reinterpret_cast<PFN_vkVoidFunction>(CreatePipelineLayout)},
+        {"vkDestroyPipelineLayout", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipelineLayout)},
+        {"vkCreateSampler", reinterpret_cast<PFN_vkVoidFunction>(CreateSampler)},
+        {"vkDestroySampler", reinterpret_cast<PFN_vkVoidFunction>(DestroySampler)},
+        {"vkCreateDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(CreateDescriptorSetLayout)},
+        {"vkDestroyDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(DestroyDescriptorSetLayout)},
+        {"vkCreateDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(CreateDescriptorPool)},
+        {"vkDestroyDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyDescriptorPool)},
+        {"vkResetDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(ResetDescriptorPool)},
+        {"vkAllocateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(AllocateDescriptorSets)},
+        {"vkFreeDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(FreeDescriptorSets)},
+        {"vkUpdateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(UpdateDescriptorSets)},
+        {"vkCmdSetViewport", reinterpret_cast<PFN_vkVoidFunction>(CmdSetViewport)},
+        {"vkCmdSetScissor", reinterpret_cast<PFN_vkVoidFunction>(CmdSetScissor)},
+        {"vkCmdSetLineWidth", reinterpret_cast<PFN_vkVoidFunction>(CmdSetLineWidth)},
+        {"vkCmdSetDepthBias", reinterpret_cast<PFN_vkVoidFunction>(CmdSetDepthBias)},
+        {"vkCmdSetBlendConstants", reinterpret_cast<PFN_vkVoidFunction>(CmdSetBlendConstants)},
+        {"vkCmdSetDepthBounds", reinterpret_cast<PFN_vkVoidFunction>(CmdSetDepthBounds)},
+        {"vkCmdSetStencilCompareMask", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilCompareMask)},
+        {"vkCmdSetStencilWriteMask", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilWriteMask)},
+        {"vkCmdSetStencilReference", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilReference)},
+        {"vkAllocateCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers)},
+        {"vkFreeCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(FreeCommandBuffers)},
+        {"vkBeginCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(BeginCommandBuffer)},
+        {"vkEndCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(EndCommandBuffer)},
+        {"vkResetCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(ResetCommandBuffer)},
+        {"vkCmdBindPipeline", reinterpret_cast<PFN_vkVoidFunction>(CmdBindPipeline)},
+        {"vkCmdBindDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(CmdBindDescriptorSets)},
+        {"vkCmdBindVertexBuffers", reinterpret_cast<PFN_vkVoidFunction>(CmdBindVertexBuffers)},
+        {"vkCmdBindIndexBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdBindIndexBuffer)},
+        {"vkCmdDraw", reinterpret_cast<PFN_vkVoidFunction>(CmdDraw)},
+        {"vkCmdDrawIndexed", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndexed)},
+        {"vkCmdDrawIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndirect)},
+        {"vkCmdDrawIndexedIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndexedIndirect)},
+        {"vkCmdDispatch", reinterpret_cast<PFN_vkVoidFunction>(CmdDispatch)},
+        {"vkCmdDispatchIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDispatchIndirect)},
+        {"vkCmdCopyBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyBuffer)},
+        {"vkCmdCopyImage", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyImage)},
+        {"vkCmdBlitImage", reinterpret_cast<PFN_vkVoidFunction>(CmdBlitImage)},
+        {"vkCmdCopyBufferToImage", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyBufferToImage)},
+        {"vkCmdCopyImageToBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyImageToBuffer)},
+        {"vkCmdUpdateBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdUpdateBuffer)},
+        {"vkCmdFillBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdFillBuffer)},
+        {"vkCmdClearColorImage", reinterpret_cast<PFN_vkVoidFunction>(CmdClearColorImage)},
+        {"vkCmdClearDepthStencilImage", reinterpret_cast<PFN_vkVoidFunction>(CmdClearDepthStencilImage)},
+        {"vkCmdClearAttachments", reinterpret_cast<PFN_vkVoidFunction>(CmdClearAttachments)},
+        {"vkCmdResolveImage", reinterpret_cast<PFN_vkVoidFunction>(CmdResolveImage)},
+        {"vkCmdSetEvent", reinterpret_cast<PFN_vkVoidFunction>(CmdSetEvent)},
+        {"vkCmdResetEvent", reinterpret_cast<PFN_vkVoidFunction>(CmdResetEvent)},
+        {"vkCmdWaitEvents", reinterpret_cast<PFN_vkVoidFunction>(CmdWaitEvents)},
+        {"vkCmdPipelineBarrier", reinterpret_cast<PFN_vkVoidFunction>(CmdPipelineBarrier)},
+        {"vkCmdBeginQuery", reinterpret_cast<PFN_vkVoidFunction>(CmdBeginQuery)},
+        {"vkCmdEndQuery", reinterpret_cast<PFN_vkVoidFunction>(CmdEndQuery)},
+        {"vkCmdResetQueryPool", reinterpret_cast<PFN_vkVoidFunction>(CmdResetQueryPool)},
+        {"vkCmdWriteTimestamp", reinterpret_cast<PFN_vkVoidFunction>(CmdWriteTimestamp)},
+        {"vkCmdCopyQueryPoolResults", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyQueryPoolResults)},
+        {"vkCmdPushConstants", reinterpret_cast<PFN_vkVoidFunction>(CmdPushConstants)},
+        {"vkCreateFramebuffer", reinterpret_cast<PFN_vkVoidFunction>(CreateFramebuffer)},
+        {"vkDestroyFramebuffer", reinterpret_cast<PFN_vkVoidFunction>(DestroyFramebuffer)},
+        {"vkCreateRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CreateRenderPass)},
+        {"vkDestroyRenderPass", reinterpret_cast<PFN_vkVoidFunction>(DestroyRenderPass)},
+        {"vkGetRenderAreaGranularity", reinterpret_cast<PFN_vkVoidFunction>(GetRenderAreaGranularity)},
+        {"vkCreateCommandPool", reinterpret_cast<PFN_vkVoidFunction>(CreateCommandPool)},
+        {"vkDestroyCommandPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyCommandPool)},
+        {"vkResetCommandPool", reinterpret_cast<PFN_vkVoidFunction>(ResetCommandPool)},
+        {"vkCmdBeginRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CmdBeginRenderPass)},
+        {"vkCmdNextSubpass", reinterpret_cast<PFN_vkVoidFunction>(CmdNextSubpass)},
+        {"vkCmdExecuteCommands", reinterpret_cast<PFN_vkVoidFunction>(CmdExecuteCommands)},
+        {"vkCmdEndRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CmdEndRenderPass)},
     };
 
     for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) {
@@ -4487,51 +5203,136 @@
     return nullptr;
 }
 
+static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkDevice device) {
+    static const struct {
+        const char *name;
+        PFN_vkVoidFunction proc;
+    } wsi_device_commands[] = {
+        {"vkCreateSwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR)},
+        {"vkGetSwapchainImagesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR)},
+        {"vkAcquireNextImageKHR", reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR)},
+        {"vkQueuePresentKHR", reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR)},
+    };
+
+    if (device) {
+        layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+        if (!device_data->wsi_enabled)
+            return nullptr;
+    }
+
+    for (size_t i = 0; i < ARRAY_SIZE(wsi_device_commands); i++) {
+        if (!strcmp(wsi_device_commands[i].name, name))
+            return wsi_device_commands[i].proc;
+    }
+
+    return nullptr;
+}
+
+static PFN_vkVoidFunction InterceptWsiEnabledCommand(const char *name, VkInstance instance) {
+    static const struct {
+        const char *name;
+        PFN_vkVoidFunction proc;
+    } wsi_instance_commands[] = {
+        {"vkGetPhysicalDeviceSurfaceSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR)},
+        {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
+         reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR)},
+        {"vkGetPhysicalDeviceSurfaceFormatsKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR)},
+        {"vkGetPhysicalDeviceSurfacePresentModesKHR",
+         reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR)},
+    };
+
+    VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance);
+    if (instance_extension_map.size() == 0 || !instance_extension_map[pTable].wsi_enabled)
+        return nullptr;
+
+    for (size_t i = 0; i < ARRAY_SIZE(wsi_instance_commands); i++) {
+        if (!strcmp(wsi_instance_commands[i].name, name))
+            return wsi_instance_commands[i].proc;
+    }
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    if ((instance_extension_map[pTable].win32_enabled == true) && !strcmp("vkCreateWin32SurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateWin32SurfaceKHR);
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    if ((instance_extension_map[pTable].xcb_enabled == true) && !strcmp("vkCreateXcbSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateXcbSurfaceKHR);
+    if ((instance_extension_map[pTable].xcb_enabled == true) && !strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXcbPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    if ((instance_extension_map[pTable].xlib_enabled == true) && !strcmp("vkCreateXlibSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateXlibSurfaceKHR);
+    if ((instance_extension_map[pTable].xlib_enabled == true) && !strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXlibPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    if ((instance_extension_map[pTable].mir_enabled == true) && !strcmp("vkCreateMirSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateMirSurfaceKHR);
+    if ((instance_extension_map[pTable].mir_enabled == true) && !strcmp("vkGetPhysicalDeviceMirPresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMirPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_MIR_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    if ((instance_extension_map[pTable].wayland_enabled == true) && !strcmp("vkCreateWaylandSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateWaylandSurfaceKHR);
+    if ((instance_extension_map[pTable].wayland_enabled == true) &&
+        !strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWaylandPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+    if ((instance_extension_map[pTable].android_enabled == true) && !strcmp("vkCreateAndroidSurfaceKHR", name))
+        return reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR);
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+    return nullptr;
+}
+
 } // namespace parameter_validation
 
 // vk_layer_logging.h expects these to be defined
 
-VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
-                               const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instance,
+                                                              const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+                                                              const VkAllocationCallbacks *pAllocator,
+                                                              VkDebugReportCallbackEXT *pMsgCallback) {
     return parameter_validation::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
 }
 
-VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,
-                                                                           VkDebugReportCallbackEXT msgCallback,
-                                                                           const VkAllocationCallbacks *pAllocator) {
+VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
+                                                           const VkAllocationCallbacks *pAllocator) {
     parameter_validation::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
 }
 
-VKAPI_ATTR void VKAPI_CALL
-vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
-                        size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+                                                   VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+                                                   int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
     parameter_validation::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
 }
 
 // loader-layer interface v0
 
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
-    return util_GetExtensionProperties(1, parameter_validation::instance_extensions, pCount, pProperties);
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
+                                                                                      VkExtensionProperties *pProperties) {
+    return parameter_validation::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
 }
 
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &parameter_validation::global_layer, pCount, pProperties);
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
+                                                                                  VkLayerProperties *pProperties) {
+    return parameter_validation::EnumerateInstanceLayerProperties(pCount, pProperties);
 }
 
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
-
-    /* parameter_validation's physical device layers are the same as global */
-    return util_GetLayerProperties(1, &parameter_validation::global_layer, pCount, pProperties);
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
+                                                                                VkLayerProperties *pProperties) {
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return parameter_validation::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                                     const char *pLayerName, uint32_t *pCount,
                                                                                     VkExtensionProperties *pProperties) {
-    // the layer command handles VK_NULL_HANDLE just fine
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
     return parameter_validation::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
 }
 
@@ -4540,14 +5341,5 @@
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
-    if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties);
-    if (!strcmp(funcName, "vkGetInstanceProcAddr"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr);
-
     return parameter_validation::GetInstanceProcAddr(instance, funcName);
 }
diff --git a/layers/parameter_validation_utils.h b/layers/parameter_validation_utils.h
index effd053..dbe8a81 100644
--- a/layers/parameter_validation_utils.h
+++ b/layers/parameter_validation_utils.h
@@ -49,6 +49,10 @@
     UNRECOGNIZED_VALUE,   // A Vulkan enumeration, VkFlags, or VkBool32 parameter
                           // contains a value that is not recognized as valid for
                           // that type.
+    DEVICE_LIMIT,         // A specified parameter exceeds the limits returned
+                          // by the physical device
+    DEVICE_FEATURE,       // Use of a requested feature is not supported by
+                          // the device
     FAILURE_RETURN_CODE,  // A Vulkan return code indicating a failure condition
                           // was encountered.
 };
@@ -61,6 +65,17 @@
 // Layer name string to be logged with validation messages.
 const char LayerName[] = "ParameterValidation";
 
+// Enables for display-related instance extensions
+struct instance_extension_enables {
+    bool wsi_enabled;
+    bool xlib_enabled;
+    bool xcb_enabled;
+    bool wayland_enabled;
+    bool mir_enabled;
+    bool android_enabled;
+    bool win32_enabled;
+};
+
 // String returned by string_VkStructureType for an unrecognized type.
 const std::string UnsupportedStructureTypeString = "Unhandled VkStructureType";
 
@@ -123,14 +138,14 @@
  */
 static bool validate_required_pointer(debug_report_data *report_data, const char *apiName, const char *parameterName,
                                       const void *value) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if (value == NULL) {
-        skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName, parameterName);
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -153,21 +168,21 @@
 template <typename T>
 bool validate_array(debug_report_data *report_data, const char *apiName, const char *countName, const char *arrayName, T count,
                     const void *array, bool countRequired, bool arrayRequired) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     // Count parameters not tagged as optional cannot be 0
     if ((count == 0) && countRequired) {
-        skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             REQUIRED_PARAMETER, LayerName, "%s: parameter %s must be greater than 0", apiName, countName);
     }
 
     // Array parameters not tagged as optional cannot be NULL, unless the count is 0
     if ((array == NULL) && arrayRequired && (count != 0)) {
-        skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName, arrayName);
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -193,19 +208,19 @@
 template <typename T>
 bool validate_array(debug_report_data *report_data, const char *apiName, const char *countName, const char *arrayName,
     const T *count, const void *array, bool countPtrRequired, bool countValueRequired, bool arrayRequired) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if (count == NULL) {
         if (countPtrRequired) {
-            skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                 REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName, countName);
         }
     }
     else {
-        skipCall |= validate_array(report_data, apiName, countName, arrayName, (*count), array, countValueRequired, arrayRequired);
+        skip_call |= validate_array(report_data, apiName, countName, arrayName, (*count), array, countValueRequired, arrayRequired);
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -227,21 +242,21 @@
 template <typename T>
 bool validate_struct_type(debug_report_data *report_data, const char *apiName, const char *parameterName, const char *sTypeName,
                           const T *value, VkStructureType sType, bool required) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if (value == NULL) {
         if (required) {
-            skipCall |=
+            skip_call |=
                 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                         REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName, parameterName);
         }
     } else if (value->sType != sType) {
-        skipCall |=
+        skip_call |=
             log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                     INVALID_STRUCT_STYPE, LayerName, "%s: parameter %s->sType must be %s", apiName, parameterName, sTypeName);
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -269,19 +284,19 @@
 bool validate_struct_type_array(debug_report_data *report_data, const char *apiName, const char *countName, const char *arrayName,
                                 const char *sTypeName, const uint32_t *count, const T *array, VkStructureType sType,
                                 bool countPtrRequired, bool countValueRequired, bool arrayRequired) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if (count == NULL) {
         if (countPtrRequired) {
-            skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                                 REQUIRED_PARAMETER, LayerName, "%s: required parameter %s specified as NULL", apiName, countName);
         }
     } else {
-        skipCall |= validate_struct_type_array(report_data, apiName, countName, arrayName, sTypeName, (*count), array, sType,
+        skip_call |= validate_struct_type_array(report_data, apiName, countName, arrayName, sTypeName, (*count), array, sType,
                                                countValueRequired, arrayRequired);
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -307,22 +322,22 @@
 bool validate_struct_type_array(debug_report_data *report_data, const char *apiName, const char *countName, const char *arrayName,
                                 const char *sTypeName, uint32_t count, const T *array, VkStructureType sType, bool countRequired,
                                 bool arrayRequired) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if ((count == 0) || (array == NULL)) {
-        skipCall |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired);
+        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired);
     } else {
         // Verify that all structs in the array have the correct type
         for (uint32_t i = 0; i < count; ++i) {
             if (array[i].sType != sType) {
-                skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     __LINE__, INVALID_STRUCT_STYPE, LayerName, "%s: parameter %s[%d].sType must be %s", apiName,
                                     arrayName, i, sTypeName);
             }
         }
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -412,22 +427,22 @@
  */
 static bool validate_string_array(debug_report_data *report_data, const char *apiName, const char *countName, const char *arrayName,
                                   uint32_t count, const char *const *array, bool countRequired, bool arrayRequired) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if ((count == 0) || (array == NULL)) {
-        skipCall |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired);
+        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired);
     } else {
         // Verify that strings in the array are not NULL
         for (uint32_t i = 0; i < count; ++i) {
             if (array[i] == NULL) {
-                skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     __LINE__, REQUIRED_PARAMETER, LayerName, "%s: required parameter %s[%d] specified as NULL",
                                     apiName, arrayName, i);
             }
         }
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -438,44 +453,55 @@
  * verify that pNext is null.
  *
  * @param report_data debug_report_data object for routing validation messages.
- * @param apiName Name of API call being validated.
- * @param parameterName Name of parameter being validated.
- * @param allowedStructNames Names of allowed structs.
+ * @param api_name Name of API call being validated.
+ * @param parameter_name Name of parameter being validated.
+ * @param allowed_struct_names Names of allowed structs.
  * @param next Pointer to validate.
- * @param allowedTypeCount total number of allowed structure types.
- * @param allowedTypes array of strcuture types allowed for pNext.
+ * @param allowed_type_count Total number of allowed structure types.
+ * @param allowed_types Array of strcuture types allowed for pNext.
+ * @param header_version Version of header defining the pNext validation rules.
  * @return Boolean value indicating that the call should be skipped.
  */
-static bool validate_struct_pnext(debug_report_data *report_data, const char *apiName, const char *parameterName,
-                                  const char *allowedStructNames, const void *next, size_t allowedTypeCount,
-                                  const VkStructureType *allowedTypes) {
-    bool skipCall = false;
+static bool validate_struct_pnext(debug_report_data *report_data, const char *api_name, const char *parameter_name,
+                                  const char *allowed_struct_names, const void *next, size_t allowed_type_count,
+                                  const VkStructureType *allowed_types, uint32_t header_version) {
+    bool skip_call = false;
+    const char disclaimer[] = "This warning is based on the Valid Usage documentation for version %d of the Vulkan header.  It "
+                              "is possible that you are using a struct from a private extension or an extension that was added "
+                              "to a later version of the Vulkan header, in which case your use of %s is perfectly valid but "
+                              "is not guaranteed to work correctly with validation enabled";
 
     if (next != NULL) {
-        if (allowedTypeCount == 0) {
-            skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                                INVALID_STRUCT_PNEXT, LayerName, "%s: value of %s must be NULL", apiName, parameterName);
+        if (allowed_type_count == 0) {
+            std::string message = "%s: value of %s must be NULL.  ";
+            message += disclaimer;
+            skip_call |=
+                log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+                        INVALID_STRUCT_PNEXT, LayerName, message.c_str(), api_name, parameter_name, header_version, parameter_name);
         } else {
-            const VkStructureType *start = allowedTypes;
-            const VkStructureType *end = allowedTypes + allowedTypeCount;
+            const VkStructureType *start = allowed_types;
+            const VkStructureType *end = allowed_types + allowed_type_count;
             const GenericHeader *current = reinterpret_cast<const GenericHeader *>(next);
 
             while (current != NULL) {
                 if (std::find(start, end, current->sType) == end) {
-                    std::string typeName = string_VkStructureType(current->sType);
+                    std::string type_name = string_VkStructureType(current->sType);
 
-                    if (typeName == UnsupportedStructureTypeString) {
-                        skipCall |= log_msg(
-                            report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                            INVALID_STRUCT_PNEXT, LayerName,
-                            "%s: %s chain includes a structure with unexpected VkStructureType (%d); Allowed structures are [%s]",
-                            apiName, parameterName, current->sType, allowedStructNames);
+                    if (type_name == UnsupportedStructureTypeString) {
+                        std::string message = "%s: %s chain includes a structure with unexpected VkStructureType (%d); Allowed "
+                                              "structures are [%s].  ";
+                        message += disclaimer;
+                        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+                                             0, __LINE__, INVALID_STRUCT_PNEXT, LayerName, message.c_str(), api_name,
+                                             parameter_name, current->sType, allowed_struct_names, header_version, parameter_name);
                     } else {
-                        skipCall |= log_msg(
-                            report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                            INVALID_STRUCT_PNEXT, LayerName,
-                            "%s: %s chain includes a structure with unexpected VkStructureType %s; Allowed structures are [%s]",
-                            apiName, parameterName, typeName.c_str(), allowedStructNames);
+                        std::string message =
+                            "%s: %s chain includes a structure with unexpected VkStructureType %s; Allowed structures are [%s].  ";
+                        message += disclaimer;
+                        skip_call |=
+                            log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                                    __LINE__, INVALID_STRUCT_PNEXT, LayerName, message.c_str(), api_name, parameter_name,
+                                    type_name.c_str(), allowed_struct_names, header_version, parameter_name);
                     }
                 }
 
@@ -484,7 +510,7 @@
         }
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -499,15 +525,15 @@
 * @return Boolean value indicating that the call should be skipped.
 */
 static bool validate_bool32(debug_report_data *report_data, const char *apiName, const char *parameterName, VkBool32 value) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if ((value != VK_TRUE) && (value != VK_FALSE)) {
-        skipCall |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             UNRECOGNIZED_VALUE, LayerName, "%s: value of %s (%d) is neither VK_TRUE nor VK_FALSE", apiName,
                             parameterName, value);
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -532,17 +558,17 @@
 template <typename T>
 bool validate_ranged_enum(debug_report_data *report_data, const char *apiName, const char *parameterName, const char *enumName,
                           T begin, T end, T value) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if (((value < begin) || (value > end)) && !is_extension_added_token(value)) {
-        skipCall |=
+        skip_call |=
             log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                     UNRECOGNIZED_VALUE, LayerName, "%s: value of %s (%d) does not fall within the begin..end range of the core %s "
                                                    "enumeration tokens and is not an extension added token",
                     apiName, parameterName, value, enumName);
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
@@ -572,14 +598,14 @@
 static bool validate_ranged_enum_array(debug_report_data *report_data, const char *apiName, const char *countName,
                                        const char *arrayName, const char *enumName, T begin, T end, uint32_t count, const T *array,
                                        bool countRequired, bool arrayRequired) {
-    bool skipCall = false;
+    bool skip_call = false;
 
     if ((count == 0) || (array == NULL)) {
-        skipCall |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired);
+        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, array, countRequired, arrayRequired);
     } else {
         for (uint32_t i = 0; i < count; ++i) {
             if (((array[i] < begin) || (array[i] > end)) && !is_extension_added_token(array[i])) {
-                skipCall |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     __LINE__, UNRECOGNIZED_VALUE, LayerName,
                                     "%s: value of %s[%d] (%d) does not fall within the begin..end range of the core %s "
                                     "enumeration tokens and is not an extension added token",
@@ -588,7 +614,7 @@
         }
     }
 
-    return skipCall;
+    return skip_call;
 }
 
 /**
diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp
index b603ec7..abba131 100644
--- a/layers/swapchain.cpp
+++ b/layers/swapchain.cpp
@@ -42,22 +42,12 @@
     "VK_LAYER_LUNARG_swapchain", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer",
 };
 
-static void createDeviceRegisterExtensions(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
-                                           VkDevice device) {
+static void checkDeviceRegisterExtensions(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
+                                          VkDevice device) {
     uint32_t i;
     layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
 
-    VkLayerDispatchTable *pDisp = my_device_data->device_dispatch_table;
-    PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
-
-    pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
-    pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
-    pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
-    pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
-    pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
-    pDisp->GetDeviceQueue = (PFN_vkGetDeviceQueue)gpa(device, "vkGetDeviceQueue");
-
     SwpPhysicalDevice *pPhysicalDevice = NULL;
     {
         auto it = my_instance_data->physicalDeviceMap.find(physicalDevice);
@@ -87,53 +77,15 @@
     }
 }
 
-static void createInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
+static void checkInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
     uint32_t i;
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    VkLayerInstanceDispatchTable *pDisp = my_data->instance_dispatch_table;
-    PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
-    pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)gpa(instance, "vkCreateAndroidSurfaceKHR");
-#endif // VK_USE_PLATFORM_ANDROID_KHR
-#ifdef VK_USE_PLATFORM_MIR_KHR
-    pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)gpa(instance, "vkCreateMirSurfaceKHR");
-    pDisp->GetPhysicalDeviceMirPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_MIR_KHR
-#ifdef VK_USE_PLATFORM_WAYLAND_KHR
-    pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)gpa(instance, "vkCreateWaylandSurfaceKHR");
-    pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_WAYLAND_KHR
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-    pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(instance, "vkCreateWin32SurfaceKHR");
-    pDisp->GetPhysicalDeviceWin32PresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
-#endif // VK_USE_PLATFORM_WIN32_KHR
-#ifdef VK_USE_PLATFORM_XCB_KHR
-    pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)gpa(instance, "vkCreateXcbSurfaceKHR");
-    pDisp->GetPhysicalDeviceXcbPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_XCB_KHR
-#ifdef VK_USE_PLATFORM_XLIB_KHR
-    pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)gpa(instance, "vkCreateXlibSurfaceKHR");
-    pDisp->GetPhysicalDeviceXlibPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_XLIB_KHR
-    pDisp->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(instance, "vkDestroySurfaceKHR");
-    pDisp->GetPhysicalDeviceSurfaceSupportKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
-    pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
-    pDisp->GetPhysicalDeviceSurfaceFormatsKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
-    pDisp->GetPhysicalDeviceSurfacePresentModesKHR =
-        (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
 
     // Remember this instance, and whether the VK_KHR_surface extension
     // was enabled for it:
     my_data->instanceMap[instance].instance = instance;
     my_data->instanceMap[instance].surfaceExtensionEnabled = false;
+    my_data->instanceMap[instance].displayExtensionEnabled = false;
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     my_data->instanceMap[instance].androidSurfaceExtensionEnabled = false;
 #endif // VK_USE_PLATFORM_ANDROID_KHR
@@ -166,6 +118,10 @@
 
             my_data->instanceMap[instance].surfaceExtensionEnabled = true;
         }
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
+
+            my_data->instanceMap[instance].displayExtensionEnabled = true;
+        }
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
 
@@ -259,7 +215,7 @@
                                                         pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
 
     // Call the following function after my_data is initialized:
-    createInstanceRegisterExtensions(pCreateInfo, *pInstance);
+    checkInstanceRegisterExtensions(pCreateInfo, *pInstance);
     init_swapchain(my_data, pAllocator);
 
     return result;
@@ -400,10 +356,10 @@
             skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->CreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
         lock.lock();
 
@@ -422,6 +378,8 @@
             // Point to the associated SwpInstance:
             pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -460,10 +418,10 @@
             skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->CreateMirSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
         lock.lock();
 
@@ -482,6 +440,8 @@
             // Point to the associated SwpInstance:
             pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -555,10 +515,10 @@
             skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
         lock.lock();
 
@@ -577,6 +537,8 @@
             // Point to the associated SwpInstance:
             pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -650,10 +612,10 @@
             skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
         lock.lock();
 
@@ -672,6 +634,8 @@
             // Point to the associated SwpInstance:
             pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -743,10 +707,10 @@
             skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
         lock.lock();
 
@@ -765,6 +729,8 @@
             // Point to the associated SwpInstance:
             pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -838,10 +804,10 @@
             skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
         lock.lock();
 
@@ -860,6 +826,8 @@
             // Point to the associated SwpInstance:
             pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -901,6 +869,301 @@
 }
 #endif // VK_USE_PLATFORM_XLIB_KHR
 
+VKAPI_ATTR VkResult VKAPI_CALL 
+GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties) {
+    VkResult result = VK_SUCCESS;
+    bool skipCall = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    SwpPhysicalDevice *pPhysicalDevice = NULL;
+    {
+        auto it = my_data->physicalDeviceMap.find(physicalDevice);
+        pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
+    }
+
+    if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
+                              "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__,
+                              VK_KHR_DISPLAY_EXTENSION_NAME);
+    }
+
+    if (!pPropertyCount) {
+        skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pPropertyCount");
+    }
+    // TODO add check for the count being consistent
+    lock.unlock();
+
+    if (!skipCall) {
+        result = my_data->instance_dispatch_table->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
+        return result;
+    }
+    return VK_ERROR_VALIDATION_FAILED_EXT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL 
+GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
+    VkResult result = VK_SUCCESS;
+    bool skipCall = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    SwpPhysicalDevice *pPhysicalDevice = NULL;
+    {
+        auto it = my_data->physicalDeviceMap.find(physicalDevice);
+        pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
+    }
+
+    if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
+                              "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__,
+                              VK_KHR_DISPLAY_EXTENSION_NAME);
+    }
+
+    if (!pPropertyCount) {
+        skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pPropertyCount");
+    }
+    // TODO add check for the count being consistent
+    lock.unlock();
+
+    if (!skipCall) {
+        result = my_data->instance_dispatch_table->GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
+
+        lock.lock();
+        if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
+        {
+            pPhysicalDevice->displayPlanePropertyCount = *pPropertyCount;
+            pPhysicalDevice->gotDisplayPlanePropertyCount = true;
+        }
+	// TODO store the properties for later checks
+        lock.unlock();
+
+        return result;
+    }
+    return VK_ERROR_VALIDATION_FAILED_EXT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL 
+GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays) {
+    VkResult result = VK_SUCCESS;
+    bool skipCall = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    SwpPhysicalDevice *pPhysicalDevice = NULL;
+    {
+        auto it = my_data->physicalDeviceMap.find(physicalDevice);
+        pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
+    }
+
+    if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
+                              "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__,
+                              VK_KHR_DISPLAY_EXTENSION_NAME);
+    }
+
+    if (!pDisplayCount) {
+        skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pDisplayCount");
+    }
+    // TODO add check for the count being consistent
+
+    if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
+    {
+        LOG_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
+                SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,
+                "Potential problem with calling %s() without first querying vkGetPhysicalDeviceDisplayPlanePropertiesKHR.",
+                __FUNCTION__);
+    }
+
+    if (pPhysicalDevice->gotDisplayPlanePropertyCount && planeIndex >= pPhysicalDevice->displayPlanePropertyCount)
+    {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
+                SWAPCHAIN_PLANE_INDEX_TOO_LARGE,
+                "%s(): %s must be in the range [0, %d] that was returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR. Do you have the plane index hardcoded?",
+                __FUNCTION__,
+                "planeIndex",
+                pPhysicalDevice->displayPlanePropertyCount - 1);
+    }
+    lock.unlock();
+
+    if (!skipCall) {
+        result = my_data->instance_dispatch_table->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
+
+        return result;
+    }
+    // TODO validate the returned display objects
+    return VK_ERROR_VALIDATION_FAILED_EXT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL 
+GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties) {
+    VkResult result = VK_SUCCESS;
+    bool skipCall = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    SwpPhysicalDevice *pPhysicalDevice = NULL;
+    {
+        auto it = my_data->physicalDeviceMap.find(physicalDevice);
+        pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
+    }
+
+    if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
+                              "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__,
+                              VK_KHR_DISPLAY_EXTENSION_NAME);
+    }
+
+    if (!pPropertyCount) {
+        skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pPropertyCount");
+    }
+    // TODO add check for the count being consistent
+    lock.unlock();
+
+    if (!skipCall) {
+        result = my_data->instance_dispatch_table->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
+        return result;
+    }
+    // TODO store the displayMode for later checking
+    return VK_ERROR_VALIDATION_FAILED_EXT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL 
+CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode) {
+    VkResult result = VK_SUCCESS;
+    bool skipCall = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    SwpPhysicalDevice *pPhysicalDevice = NULL;
+    {
+        auto it = my_data->physicalDeviceMap.find(physicalDevice);
+        pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
+    }
+
+    if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
+                              "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__,
+                              VK_KHR_DISPLAY_EXTENSION_NAME);
+    }
+
+    if (!pCreateInfo) {
+        skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pCreateInfo");
+    }
+    lock.unlock();
+
+    // TODO more validation checks needed
+    if (!skipCall) {
+        result = my_data->instance_dispatch_table->CreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode);
+        return result;
+    }
+    
+    return VK_ERROR_VALIDATION_FAILED_EXT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL 
+GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities) {
+    VkResult result = VK_SUCCESS;
+    bool skipCall = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    SwpPhysicalDevice *pPhysicalDevice = NULL;
+    {
+        auto it = my_data->physicalDeviceMap.find(physicalDevice);
+        pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
+    }
+
+    if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance",
+                              SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
+                              "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__,
+                              VK_KHR_DISPLAY_EXTENSION_NAME);
+    }
+
+    if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
+    {
+        LOG_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
+                SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,
+                "Potential problem with calling %s() without first querying vkGetPhysicalDeviceDisplayPlanePropertiesKHR.",
+                __FUNCTION__);
+    }
+
+    if (pPhysicalDevice->gotDisplayPlanePropertyCount && planeIndex >= pPhysicalDevice->displayPlanePropertyCount)
+    {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
+                SWAPCHAIN_PLANE_INDEX_TOO_LARGE,
+                "%s(): %s must be in the range [0, %d] that was returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR. Do you have the plane index hardcoded?",
+                __FUNCTION__,
+                "planeIndex",
+                pPhysicalDevice->displayPlanePropertyCount - 1);
+    }
+
+    if (!pCapabilities) {
+        skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pCapabilities");
+    }
+    lock.unlock();
+
+    if (!skipCall) {
+        result = my_data->instance_dispatch_table->GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities);
+        return result;
+    }
+
+    return VK_ERROR_VALIDATION_FAILED_EXT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
+                       VkSurfaceKHR *pSurface) {
+    VkResult result = VK_SUCCESS;
+    bool skipCall = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    SwpInstance *pInstance = &(my_data->instanceMap[instance]);
+
+    // Validate that the platform extension was enabled:
+    if (pInstance && !pInstance->displayExtensionEnabled) {
+        skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pInstance, "VkInstance", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
+                              "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__,
+                              VK_KHR_DISPLAY_EXTENSION_NAME);
+    }
+
+    if (!pCreateInfo) {
+        skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
+    } else {
+        if (pCreateInfo->sType != VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR) {
+            skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
+                                              "VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR");
+        }
+        if (pCreateInfo->pNext != NULL) {
+            skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
+        }
+    }
+
+    // TODO more validation checks
+    if (!skipCall) {
+        // Call down the call chain:
+        lock.unlock();
+        result = my_data->instance_dispatch_table->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+        lock.lock();
+
+        // Obtain this pointer again after locking:
+        pInstance = &(my_data->instanceMap[instance]);
+        if ((result == VK_SUCCESS) && pInstance && pSurface) {
+            // Record the VkSurfaceKHR returned by the ICD:
+            my_data->surfaceMap[*pSurface].surface = *pSurface;
+            my_data->surfaceMap[*pSurface].pInstance = pInstance;
+            my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
+            my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
+            my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
+            // Point to the associated SwpInstance:
+            pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
+        }
+        lock.unlock();
+        return result;
+    }
+    return VK_ERROR_VALIDATION_FAILED_EXT;
+}
+
 VKAPI_ATTR void VKAPI_CALL
 DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) {
     bool skipCall = false;
@@ -1030,7 +1293,7 @@
     layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
 
     my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
-    createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice);
+    checkDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice);
 
     return result;
 }
@@ -1113,10 +1376,10 @@
     if (!pSupported) {
         skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pSupported");
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface,
                                                                                       pSupported);
         lock.lock();
@@ -1146,6 +1409,8 @@
                 }
             }
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1174,10 +1439,10 @@
     if (!pSurfaceCapabilities) {
         skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pSurfaceCapabilities");
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface,
                                                                                            pSurfaceCapabilities);
         lock.lock();
@@ -1193,6 +1458,8 @@
             // FIXME: NEED TO COPY THIS DATA, BECAUSE pSurfaceCapabilities POINTS TO APP-ALLOCATED DATA
             pPhysicalDevice->surfaceCapabilities = *pSurfaceCapabilities;
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1238,10 +1505,10 @@
                 *pSurfaceFormatCount, pPhysicalDevice->surfaceFormatCount);
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount,
                                                                                       pSurfaceFormats);
         lock.lock();
@@ -1268,6 +1535,8 @@
                 pPhysicalDevice->surfaceFormatCount = 0;
             }
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1313,10 +1582,10 @@
                 *pPresentModeCount, pPhysicalDevice->presentModeCount);
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface,
                                                                                            pPresentModeCount, pPresentModes);
         lock.lock();
@@ -1343,6 +1612,8 @@
                 pPhysicalDevice->presentModeCount = 0;
             }
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1413,10 +1684,13 @@
         SwpSurface *pSurface = ((pPhysicalDevice) ? pPhysicalDevice->supportedSurfaces[pCreateInfo->surface] : NULL);
         if (!pSurface) {
             skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_CREATE_UNSUPPORTED_SURFACE,
-                                  "%s() called with pCreateInfo->surface that "
-                                  "was not returned by "
+                                  "The surface in pCreateInfo->surface, that "
+                                  "was given to %s(), must be a surface that "
+                                  "is supported by the device as determined "
+                                  "by vkGetPhysicalDeviceSurfaceSupportKHR().  "
+                                  "However, "
                                   "vkGetPhysicalDeviceSurfaceSupportKHR() "
-                                  "for the device.",
+                                  "was never called with this surface.",
                                   fn);
         }
 
@@ -1519,13 +1793,13 @@
                                 reinterpret_cast<uint64_t &>(device), __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_COMPOSITE_ALPHA,
                                 LAYER_NAME, "%s", errorString.c_str());
         }
-        // Validate pCreateInfo->imageArraySize against
-        // VkSurfaceCapabilitiesKHR::maxImageArraySize:
+        // Validate pCreateInfo->imageArrayLayers against
+        // VkSurfaceCapabilitiesKHR::maxImageArrayLayers:
         if ((pCreateInfo->imageArrayLayers < 1) || (pCreateInfo->imageArrayLayers > pCapabilities->maxImageArrayLayers)) {
             skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
-                                  SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_SIZE, "%s() called with a non-supported "
-                                                                            "pCreateInfo->imageArraySize (i.e. %d).  "
-                                                                            "Minimum value is 1, maximum value is %d.",
+                                  SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_LAYERS, "%s() called with a non-supported "
+                                                                              "pCreateInfo->imageArrayLayers (i.e. %d).  "
+                                                                              "Minimum value is 1, maximum value is %d.",
                                   fn, pCreateInfo->imageArrayLayers, pCapabilities->maxImageArrayLayers);
         }
         // Validate pCreateInfo->imageUsage against
@@ -1684,10 +1958,10 @@
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     bool skipCall = validateCreateSwapchainKHR(device, pCreateInfo, pSwapchain);
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->device_dispatch_table->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
         lock.lock();
 
@@ -1717,6 +1991,8 @@
                 pSurface->swapchains[*pSwapchain] = &my_data->swapchainMap[*pSwapchain];
             }
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1827,10 +2103,10 @@
                 *pSwapchainImageCount, pSwapchain->imageCount);
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->device_dispatch_table->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
         lock.lock();
 
@@ -1852,6 +2128,8 @@
                 pSwapchain->images[i].acquiredByApp = false;
             }
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1929,10 +2207,10 @@
     if (!pImageIndex) {
         skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pImageIndex");
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->device_dispatch_table->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
         lock.lock();
 
@@ -1945,6 +2223,8 @@
             // Change the state of the image (now acquired by the application):
             pSwapchain->images[*pImageIndex].acquiredByApp = true;
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2039,10 +2319,10 @@
             }
         }
     }
+    lock.unlock();
 
     if (!skipCall) {
         // Call down the call chain:
-        lock.unlock();
         result = my_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo);
         lock.lock();
 
@@ -2061,6 +2341,8 @@
                 }
             }
         }
+        lock.unlock();
+
         return result;
     }
     return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2099,7 +2381,7 @@
         my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
-        result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
+        result = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
     }
     return result;
 }
@@ -2121,6 +2403,24 @@
                                                             pMsg);
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &swapchain_layer, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &swapchain_layer, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, swapchain_layer.layerName))
+        return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
+
+    return VK_ERROR_LAYER_NOT_PRESENT;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                   const char *pLayerName, uint32_t *pCount,
                                                                   VkExtensionProperties *pProperties) {
@@ -2204,15 +2504,13 @@
         { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) },
         { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) },
         { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) },
+        { "vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties) },
+        { "vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties) },
+        { "vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties) },
         { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) },
         { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) },
     };
 
-    // we should never be queried for these commands
-    assert(strcmp(name, "vkEnumerateInstanceLayerProperties") &&
-           strcmp(name, "vkEnumerateInstanceExtensionProperties") &&
-           strcmp(name, "vkEnumerateDeviceLayerProperties"));
-
     for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
         if (!strcmp(core_instance_commands[i].name, name))
             return core_instance_commands[i].proc;
@@ -2255,6 +2553,13 @@
         { "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR) },
         { "vkGetPhysicalDeviceSurfaceFormatsKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR) },
         { "vkGetPhysicalDeviceSurfacePresentModesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR) },
+        { "vkGetPhysicalDeviceDisplayPropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceDisplayPropertiesKHR) },
+        { "vkGetPhysicalDeviceDisplayPlanePropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceDisplayPlanePropertiesKHR) },
+        { "vkGetDisplayPlaneSupportedDisplaysKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayPlaneSupportedDisplaysKHR) },
+        { "vkGetDisplayModePropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayModePropertiesKHR) },
+        { "vkCreateDisplayModeKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateDisplayModeKHR) },
+        { "vkGetDisplayPlaneCapabilitiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayPlaneCapabilitiesKHR) },
+        { "vkCreateDisplayPlaneSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateDisplayPlaneSurfaceKHR) },
     };
 
     // do not check if VK_KHR_*_surface is enabled (why?)
@@ -2331,27 +2636,30 @@
     swapchain::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
 }
 
-// loader-layer interface v0
+// loader-layer interface v0, just wrappers since there is only a layer
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
-    return util_GetExtensionProperties(ARRAY_SIZE(swapchain::instance_extensions), swapchain::instance_extensions, pCount, pProperties);
+    return swapchain::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &swapchain::swapchain_layer, pCount, pProperties);
+    return swapchain::EnumerateInstanceLayerProperties(pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &swapchain::swapchain_layer, pCount, pProperties);
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return swapchain::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                                     const char *pLayerName, uint32_t *pCount,
                                                                                     VkExtensionProperties *pProperties) {
-    // the layer command handles VK_NULL_HANDLE just fine
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
     return swapchain::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
 }
 
@@ -2360,14 +2668,5 @@
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
-    if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties);
-    if (!strcmp(funcName, "vkGetInstanceProcAddr"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr);
-
     return swapchain::GetInstanceProcAddr(instance, funcName);
 }
diff --git a/layers/swapchain.h b/layers/swapchain.h
index a8b2d8b..8991d80 100644
--- a/layers/swapchain.h
+++ b/layers/swapchain.h
@@ -45,7 +45,7 @@
     SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN, // Called vkCreateSwapchainKHR() with imageExtent that doesn't match window's extent
     SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM,    // Called vkCreateSwapchainKHR() with a non-supported preTransform
     SWAPCHAIN_CREATE_SWAP_BAD_COMPOSITE_ALPHA,  // Called vkCreateSwapchainKHR() with a non-supported compositeAlpha
-    SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_SIZE,   // Called vkCreateSwapchainKHR() with a non-supported imageArraySize
+    SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_LAYERS, // Called vkCreateSwapchainKHR() with a non-supported imageArrayLayers
     SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS,  // Called vkCreateSwapchainKHR() with a non-supported imageUsageFlags
     SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE,  // Called vkCreateSwapchainKHR() with a non-supported imageColorSpace
     SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT,       // Called vkCreateSwapchainKHR() with a non-supported imageFormat
@@ -74,6 +74,9 @@
     SWAPCHAIN_SURFACE_NOT_SUPPORTED_WITH_QUEUE, // A surface is not supported by a given queueFamilyIndex, as seen by
                                                 // vkGetPhysicalDeviceSurfaceSupportKHR()
     SWAPCHAIN_NO_SYNC_FOR_ACQUIRE,      // vkAcquireNextImageKHR should be called with a valid semaphore and/or fence
+    SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,     // vkGetDisplayPlaneSupportedDisplaysKHR should be called after querying 
+                                                        // device display plane properties
+    SWAPCHAIN_PLANE_INDEX_TOO_LARGE,    // a planeIndex value is larger than what vkGetDisplayPlaneSupportedDisplaysKHR returns
 };
 
 // The following is for logging error messages:
@@ -161,6 +164,9 @@
     // Set to true if VK_KHR_SURFACE_EXTENSION_NAME was enabled for this VkInstance:
     bool surfaceExtensionEnabled;
 
+    // Set to true if VK_KHR_DISPLAY_EXTENSION_NAME was enabled for this VkInstance:
+    bool displayExtensionEnabled;
+
 // TODO: Add additional booleans for platform-specific extensions:
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     // Set to true if VK_KHR_ANDROID_SURFACE_EXTENSION_NAME was enabled for this VkInstance:
@@ -251,6 +257,10 @@
     // Count and VkPresentModeKHR's returned by vkGetPhysicalDeviceSurfacePresentModesKHR():
     uint32_t presentModeCount;
     VkPresentModeKHR *pPresentModes;
+
+    // Count returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR():
+    uint32_t displayPlanePropertyCount;
+    bool gotDisplayPlanePropertyCount;
 };
 
 // Create one of these for each VkDevice within a VkInstance:
diff --git a/layers/threading.cpp b/layers/threading.cpp
index 2de0052..2228d90 100644
--- a/layers/threading.cpp
+++ b/layers/threading.cpp
@@ -94,9 +94,16 @@
         }
     }
 
-    startWriteObject(my_data, instance);
+    bool threadChecks = startMultiThread();
+    if (threadChecks) {
+        startWriteObject(my_data, instance);
+    }
     pTable->DestroyInstance(instance, pAllocator);
-    finishWriteObject(my_data, instance);
+    if (threadChecks) {
+        finishWriteObject(my_data, instance);
+    } else {
+        finishMultiThread();
+    }
 
     // Disable and cleanup the temporary callback(s):
     if (callback_setup) {
@@ -153,9 +160,16 @@
 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
     dispatch_key key = get_dispatch_key(device);
     layer_data *dev_data = get_my_data_ptr(key, layer_data_map);
-    startWriteObject(dev_data, device);
+    bool threadChecks = startMultiThread();
+    if (threadChecks) {
+        startWriteObject(dev_data, device);
+    }
     dev_data->device_dispatch_table->DestroyDevice(device, pAllocator);
-    finishWriteObject(dev_data, device);
+    if (threadChecks) {
+        finishWriteObject(dev_data, device);
+    } else {
+        finishMultiThread();
+    }
     layer_data_map.erase(key);
 }
 
@@ -176,6 +190,24 @@
     return NULL;
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &layerProps, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &layerProps, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, layerProps.layerName))
+        return util_GetExtensionProperties(1, threading_extensions, pCount, pProperties);
+
+    return VK_ERROR_LAYER_NOT_PRESENT;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                   const char *pLayerName, uint32_t *pCount,
                                                                   VkExtensionProperties *pProperties) {
@@ -194,16 +226,17 @@
     if (!name || name[0] != 'v' || name[1] != 'k')
         return NULL;
 
-    // we should never be queried for these commands
-    assert(strcmp(name, "vkEnumerateInstanceLayerProperties") &&
-           strcmp(name, "vkEnumerateInstanceExtensionProperties") &&
-           strcmp(name, "vkEnumerateDeviceLayerProperties"));
-
     name += 2;
     if (!strcmp(name, "CreateInstance"))
         return (PFN_vkVoidFunction)CreateInstance;
     if (!strcmp(name, "DestroyInstance"))
         return (PFN_vkVoidFunction)DestroyInstance;
+    if (!strcmp(name, "EnumerateInstanceLayerProperties"))
+        return (PFN_vkVoidFunction)EnumerateInstanceLayerProperties;
+    if (!strcmp(name, "EnumerateInstanceExtensionProperties"))
+        return (PFN_vkVoidFunction)EnumerateInstanceExtensionProperties;
+    if (!strcmp(name, "EnumerateDeviceLayerProperties"))
+        return (PFN_vkVoidFunction)EnumerateDeviceLayerProperties;
     if (!strcmp(name, "EnumerateDeviceExtensionProperties"))
         return (PFN_vkVoidFunction)EnumerateDeviceExtensionProperties;
     if (!strcmp(name, "CreateDevice"))
@@ -262,25 +295,39 @@
 CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
                              const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    startReadObject(my_data, instance);
+    bool threadChecks = startMultiThread();
+    if (threadChecks) {
+        startReadObject(my_data, instance);
+    }
     VkResult result =
         my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
     if (VK_SUCCESS == result) {
-        result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
+        result = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
     }
-    finishReadObject(my_data, instance);
+    if (threadChecks) {
+        finishReadObject(my_data, instance);
+    } else {
+        finishMultiThread();
+    }
     return result;
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks *pAllocator) {
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    startReadObject(my_data, instance);
-    startWriteObject(my_data, callback);
+    bool threadChecks = startMultiThread();
+    if (threadChecks) {
+        startReadObject(my_data, instance);
+        startWriteObject(my_data, callback);
+    }
     my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
     layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
-    finishReadObject(my_data, instance);
-    finishWriteObject(my_data, callback);
+    if (threadChecks) {
+        finishReadObject(my_data, instance);
+        finishWriteObject(my_data, callback);
+    } else {
+        finishMultiThread();
+    }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
@@ -289,17 +336,24 @@
     layer_data *my_data = get_my_data_ptr(key, layer_data_map);
     VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
     VkResult result;
-    startReadObject(my_data, device);
-    startWriteObject(my_data, pAllocateInfo->commandPool);
+    bool threadChecks = startMultiThread();
+    if (threadChecks) {
+        startReadObject(my_data, device);
+        startWriteObject(my_data, pAllocateInfo->commandPool);
+    }
 
     result = pTable->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
-    finishReadObject(my_data, device);
-    finishWriteObject(my_data, pAllocateInfo->commandPool);
+    if (threadChecks) {
+        finishReadObject(my_data, device);
+        finishWriteObject(my_data, pAllocateInfo->commandPool);
+    } else {
+        finishMultiThread();
+    }
 
     // Record mapping from command buffer to command pool
     if (VK_SUCCESS == result) {
         for (uint32_t index = 0; index < pAllocateInfo->commandBufferCount; index++) {
-            std::lock_guard<std::mutex> lock(global_lock);
+            std::lock_guard<std::mutex> lock(command_pool_lock);
             command_pool_map[pCommandBuffers[index]] = pAllocateInfo->commandPool;
         }
     }
@@ -313,19 +367,28 @@
     layer_data *my_data = get_my_data_ptr(key, layer_data_map);
     VkLayerDispatchTable *pTable = my_data->device_dispatch_table;
     const bool lockCommandPool = false; // pool is already directly locked
-    startReadObject(my_data, device);
-    startWriteObject(my_data, commandPool);
-    for (uint32_t index = 0; index < commandBufferCount; index++) {
-        startWriteObject(my_data, pCommandBuffers[index], lockCommandPool);
+    bool threadChecks = startMultiThread();
+    if (threadChecks) {
+        startReadObject(my_data, device);
+        startWriteObject(my_data, commandPool);
+        for (uint32_t index = 0; index < commandBufferCount; index++) {
+            startWriteObject(my_data, pCommandBuffers[index], lockCommandPool);
+        }
+        // The driver may immediately reuse command buffers in another thread.
+        // These updates need to be done before calling down to the driver.
+        for (uint32_t index = 0; index < commandBufferCount; index++) {
+            finishWriteObject(my_data, pCommandBuffers[index], lockCommandPool);
+            std::lock_guard<std::mutex> lock(command_pool_lock);
+            command_pool_map.erase(pCommandBuffers[index]);
+        }
     }
 
     pTable->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
-    finishReadObject(my_data, device);
-    finishWriteObject(my_data, commandPool);
-    for (uint32_t index = 0; index < commandBufferCount; index++) {
-        finishWriteObject(my_data, pCommandBuffers[index], lockCommandPool);
-        std::lock_guard<std::mutex> lock(global_lock);
-        command_pool_map.erase(pCommandBuffers[index]);
+    if (threadChecks) {
+        finishReadObject(my_data, device);
+        finishWriteObject(my_data, commandPool);
+    } else {
+        finishMultiThread();
     }
 }
 
@@ -351,26 +414,30 @@
     threading::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
 }
 
-// loader-layer interface v0
+// loader-layer interface v0, just wrappers since there is only a layer
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
-    return util_GetExtensionProperties(ARRAY_SIZE(threading::threading_extensions), threading::threading_extensions, pCount, pProperties);
+    return threading::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
 }
 
-VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &threading::layerProps, pCount, pProperties);
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
+vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    return threading::EnumerateInstanceLayerProperties(pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
-    return util_GetLayerProperties(1, &threading::layerProps, pCount, pProperties);
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return threading::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
                                                                                     const char *pLayerName, uint32_t *pCount,
                                                                                     VkExtensionProperties *pProperties) {
-    // the layer command handles VK_NULL_HANDLE just fine
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
     return threading::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
 }
 
@@ -379,14 +446,5 @@
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
-    if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties);
-    if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties);
-    if (!strcmp(funcName, "vkGetInstanceProcAddr"))
-        return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr);
-
     return threading::GetInstanceProcAddr(instance, funcName);
 }
diff --git a/layers/threading.h b/layers/threading.h
index c3db346..1d0924d 100644
--- a/layers/threading.h
+++ b/layers/threading.h
@@ -48,18 +48,37 @@
 
 struct layer_data;
 
-static std::mutex global_lock;
-static std::condition_variable global_condition;
+namespace threading {
+volatile bool vulkan_in_use = false;
+volatile bool vulkan_multi_threaded = false;
+// starting check if an application is using vulkan from multiple threads.
+inline bool startMultiThread() {
+    if (vulkan_multi_threaded) {
+        return true;
+    }
+    if (vulkan_in_use) {
+        vulkan_multi_threaded = true;
+        return true;
+    }
+    vulkan_in_use = true;
+    return false;
+}
+
+// finishing check if an application is using vulkan from multiple threads.
+inline void finishMultiThread() { vulkan_in_use = false; }
+} // namespace threading
 
 template <typename T> class counter {
   public:
     const char *typeName;
     VkDebugReportObjectTypeEXT objectType;
     std::unordered_map<T, object_use_data> uses;
+    std::mutex counter_lock;
+    std::condition_variable counter_condition;
     void startWrite(debug_report_data *report_data, T object) {
         bool skipCall = false;
         loader_platform_thread_id tid = loader_platform_get_thread_id();
-        std::unique_lock<std::mutex> lock(global_lock);
+        std::unique_lock<std::mutex> lock(counter_lock);
         if (uses.find(object) == uses.end()) {
             // There is no current use of the object.  Record writer thread.
             struct object_use_data *use_data = &uses[object];
@@ -78,7 +97,7 @@
                     if (skipCall) {
                         // Wait for thread-safe access to object instead of skipping call.
                         while (uses.find(object) != uses.end()) {
-                            global_condition.wait(lock);
+                            counter_condition.wait(lock);
                         }
                         // There is now no current use of the object.  Record writer thread.
                         struct object_use_data *use_data = &uses[object];
@@ -105,7 +124,7 @@
                     if (skipCall) {
                         // Wait for thread-safe access to object instead of skipping call.
                         while (uses.find(object) != uses.end()) {
-                            global_condition.wait(lock);
+                            counter_condition.wait(lock);
                         }
                         // There is now no current use of the object.  Record writer thread.
                         struct object_use_data *use_data = &uses[object];
@@ -128,20 +147,20 @@
 
     void finishWrite(T object) {
         // Object is no longer in use
-        std::unique_lock<std::mutex> lock(global_lock);
+        std::unique_lock<std::mutex> lock(counter_lock);
         uses[object].writer_count -= 1;
         if ((uses[object].reader_count == 0) && (uses[object].writer_count == 0)) {
             uses.erase(object);
         }
         // Notify any waiting threads that this object may be safe to use
         lock.unlock();
-        global_condition.notify_all();
+        counter_condition.notify_all();
     }
 
     void startRead(debug_report_data *report_data, T object) {
         bool skipCall = false;
         loader_platform_thread_id tid = loader_platform_get_thread_id();
-        std::unique_lock<std::mutex> lock(global_lock);
+        std::unique_lock<std::mutex> lock(counter_lock);
         if (uses.find(object) == uses.end()) {
             // There is no current use of the object.  Record reader count
             struct object_use_data *use_data = &uses[object];
@@ -157,7 +176,7 @@
             if (skipCall) {
                 // Wait for thread-safe access to object instead of skipping call.
                 while (uses.find(object) != uses.end()) {
-                    global_condition.wait(lock);
+                    counter_condition.wait(lock);
                 }
                 // There is no current use of the object.  Record reader count
                 struct object_use_data *use_data = &uses[object];
@@ -173,14 +192,14 @@
         }
     }
     void finishRead(T object) {
-        std::unique_lock<std::mutex> lock(global_lock);
+        std::unique_lock<std::mutex> lock(counter_lock);
         uses[object].reader_count -= 1;
         if ((uses[object].reader_count == 0) && (uses[object].writer_count == 0)) {
             uses.erase(object);
         }
-        // Notify and waiting threads that this object may be safe to use
+        // Notify any waiting threads that this object may be safe to use
         lock.unlock();
-        global_condition.notify_all();
+        counter_condition.notify_all();
     }
     counter(const char *name = "", VkDebugReportObjectTypeEXT type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT) {
         typeName = name;
@@ -302,12 +321,13 @@
 #endif // DISTINCT_NONDISPATCHABLE_HANDLES
 
 static std::unordered_map<void *, layer_data *> layer_data_map;
+static std::mutex command_pool_lock;
 static std::unordered_map<VkCommandBuffer, VkCommandPool> command_pool_map;
 
 // VkCommandBuffer needs check for implicit use of command pool
 static void startWriteObject(struct layer_data *my_data, VkCommandBuffer object, bool lockPool = true) {
     if (lockPool) {
-        std::unique_lock<std::mutex> lock(global_lock);
+        std::unique_lock<std::mutex> lock(command_pool_lock);
         VkCommandPool pool = command_pool_map[object];
         lock.unlock();
         startWriteObject(my_data, pool);
@@ -317,14 +337,14 @@
 static void finishWriteObject(struct layer_data *my_data, VkCommandBuffer object, bool lockPool = true) {
     my_data->c_VkCommandBuffer.finishWrite(object);
     if (lockPool) {
-        std::unique_lock<std::mutex> lock(global_lock);
+        std::unique_lock<std::mutex> lock(command_pool_lock);
         VkCommandPool pool = command_pool_map[object];
         lock.unlock();
         finishWriteObject(my_data, pool);
     }
 }
 static void startReadObject(struct layer_data *my_data, VkCommandBuffer object) {
-    std::unique_lock<std::mutex> lock(global_lock);
+    std::unique_lock<std::mutex> lock(command_pool_lock);
     VkCommandPool pool = command_pool_map[object];
     lock.unlock();
     startReadObject(my_data, pool);
@@ -332,7 +352,7 @@
 }
 static void finishReadObject(struct layer_data *my_data, VkCommandBuffer object) {
     my_data->c_VkCommandBuffer.finishRead(object);
-    std::unique_lock<std::mutex> lock(global_lock);
+    std::unique_lock<std::mutex> lock(command_pool_lock);
     VkCommandPool pool = command_pool_map[object];
     lock.unlock();
     finishReadObject(my_data, pool);
diff --git a/layers/unique_objects.h b/layers/unique_objects.h
index 9abf240..2c9eca0 100644
--- a/layers/unique_objects.h
+++ b/layers/unique_objects.h
@@ -21,10 +21,11 @@
 #include "vk_loader_platform.h"
 #include "vulkan/vulkan.h"
 
+#include <cinttypes>
+#include <memory>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <cinttypes>
 
 #include <unordered_map>
 #include <vector>
@@ -54,7 +55,7 @@
     layer_data() : wsi_enabled(false), gpu(VK_NULL_HANDLE){};
 };
 
-struct instExts {
+struct instance_extension_enables {
     bool wsi_enabled;
     bool xlib_enabled;
     bool xcb_enabled;
@@ -62,62 +63,48 @@
     bool mir_enabled;
     bool android_enabled;
     bool win32_enabled;
+    bool display_enabled;
 };
 
-static std::unordered_map<void *, struct instExts> instanceExtMap;
+static std::unordered_map<void *, struct instance_extension_enables> instanceExtMap;
 static std::unordered_map<void *, layer_data *> layer_data_map;
 static device_table_map unique_objects_device_table_map;
 static instance_table_map unique_objects_instance_table_map;
 static std::mutex global_lock; // Protect map accesses and unique_id increments
 
+struct GenericHeader {
+    VkStructureType sType;
+    void *pNext;
+};
+
+template <typename T> bool ContainsExtStruct(const T *target, VkStructureType ext_type) {
+    assert(target != nullptr);
+
+    const GenericHeader *ext_struct = reinterpret_cast<const GenericHeader *>(target->pNext);
+
+    while (ext_struct != nullptr) {
+        if (ext_struct->sType == ext_type) {
+            return true;
+        }
+
+        ext_struct = reinterpret_cast<const GenericHeader *>(ext_struct->pNext);
+    }
+
+    return false;
+}
+
 // Handle CreateInstance
-static void createInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
+static void checkInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
     uint32_t i;
     VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance);
-    PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
-
-    pDisp->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(instance, "vkDestroySurfaceKHR");
-    pDisp->GetPhysicalDeviceSurfaceSupportKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
-    pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
-    pDisp->GetPhysicalDeviceSurfaceFormatsKHR =
-        (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
-    pDisp->GetPhysicalDeviceSurfacePresentModesKHR =
-        (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-    pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(instance, "vkCreateWin32SurfaceKHR");
-    pDisp->GetPhysicalDeviceWin32PresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
-#endif // VK_USE_PLATFORM_WIN32_KHR
-#ifdef VK_USE_PLATFORM_XCB_KHR
-    pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)gpa(instance, "vkCreateXcbSurfaceKHR");
-    pDisp->GetPhysicalDeviceXcbPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_XCB_KHR
-#ifdef VK_USE_PLATFORM_XLIB_KHR
-    pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)gpa(instance, "vkCreateXlibSurfaceKHR");
-    pDisp->GetPhysicalDeviceXlibPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_XLIB_KHR
-#ifdef VK_USE_PLATFORM_MIR_KHR
-    pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)gpa(instance, "vkCreateMirSurfaceKHR");
-    pDisp->GetPhysicalDeviceMirPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
-#endif // VK_USE_PLATFORM_MIR_KHR
-#ifdef VK_USE_PLATFORM_WAYLAND_KHR
-    pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)gpa(instance, "vkCreateWaylandSurfaceKHR");
-    pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR =
-        (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
-#endif //  VK_USE_PLATFORM_WAYLAND_KHR
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
-    pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)gpa(instance, "vkCreateAndroidSurfaceKHR");
-#endif // VK_USE_PLATFORM_ANDROID_KHR
 
     instanceExtMap[pDisp] = {};
+
     for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
             instanceExtMap[pDisp].wsi_enabled = true;
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0)
+            instanceExtMap[pDisp].display_enabled = true;
 #ifdef VK_USE_PLATFORM_XLIB_KHR
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0)
             instanceExtMap[pDisp].xlib_enabled = true;
@@ -168,14 +155,16 @@
     my_data->instance = *pInstance;
     initInstanceTable(*pInstance, fpGetInstanceProcAddr, unique_objects_instance_table_map);
 
-    createInstanceRegisterExtensions(pCreateInfo, *pInstance);
+    checkInstanceRegisterExtensions(pCreateInfo, *pInstance);
 
     return result;
 }
 
 void explicit_DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
     dispatch_key key = get_dispatch_key(instance);
-    get_dispatch_table(unique_objects_instance_table_map, instance)->DestroyInstance(instance, pAllocator);
+    VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance);
+    instanceExtMap.erase(pDisp);
+    pDisp->DestroyInstance(instance, pAllocator);
     layer_data_map.erase(key);
 }
 
@@ -234,6 +223,68 @@
     layer_data_map.erase(key);
 }
 
+VkResult explicit_AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
+                                 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
+    const VkMemoryAllocateInfo *input_allocate_info = pAllocateInfo;
+    std::unique_ptr<safe_VkMemoryAllocateInfo> safe_allocate_info;
+    std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV> safe_dedicated_allocate_info;
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
+    if ((pAllocateInfo != nullptr) &&
+        ContainsExtStruct(pAllocateInfo, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)) {
+        // Assuming there is only one extension struct of this type in the list for now
+        safe_dedicated_allocate_info =
+            std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV>(new safe_VkDedicatedAllocationMemoryAllocateInfoNV);
+        safe_allocate_info = std::unique_ptr<safe_VkMemoryAllocateInfo>(new safe_VkMemoryAllocateInfo);
+
+        safe_allocate_info->initialize(pAllocateInfo);
+        input_allocate_info = reinterpret_cast<const VkMemoryAllocateInfo *>(safe_allocate_info.get());
+
+        const GenericHeader *orig_pnext = reinterpret_cast<const GenericHeader *>(pAllocateInfo->pNext);
+        GenericHeader *input_pnext = reinterpret_cast<GenericHeader *>(safe_allocate_info.get());
+        while (orig_pnext != nullptr) {
+            if (orig_pnext->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV) {
+                safe_dedicated_allocate_info->initialize(
+                    reinterpret_cast<const VkDedicatedAllocationMemoryAllocateInfoNV *>(orig_pnext));
+
+                std::unique_lock<std::mutex> lock(global_lock);
+
+                if (safe_dedicated_allocate_info->buffer != VK_NULL_HANDLE) {
+                    uint64_t local_buffer = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->buffer);
+                    safe_dedicated_allocate_info->buffer =
+                        reinterpret_cast<VkBuffer &>(my_map_data->unique_id_mapping[local_buffer]);
+                }
+
+                if (safe_dedicated_allocate_info->image != VK_NULL_HANDLE) {
+                    uint64_t local_image = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->image);
+                    safe_dedicated_allocate_info->image = reinterpret_cast<VkImage &>(my_map_data->unique_id_mapping[local_image]);
+                }
+
+                lock.unlock();
+
+                input_pnext->pNext = reinterpret_cast<GenericHeader *>(safe_dedicated_allocate_info.get());
+                input_pnext = reinterpret_cast<GenericHeader *>(input_pnext->pNext);
+            } else {
+                // TODO: generic handling of pNext copies
+            }
+
+            orig_pnext = reinterpret_cast<const GenericHeader *>(orig_pnext->pNext);
+        }
+    }
+
+    VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
+                          ->AllocateMemory(device, input_allocate_info, pAllocator, pMemory);
+
+    if (VK_SUCCESS == result) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        uint64_t unique_id = global_unique_id++;
+        my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pMemory);
+        *pMemory = reinterpret_cast<VkDeviceMemory &>(unique_id);
+    }
+
+    return result;
+}
+
 VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
                                          const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
                                          VkPipeline *pPipelines) {
@@ -401,4 +452,96 @@
     return result;
 }
 
+ #ifndef __ANDROID__
+VkResult explicit_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties)
+{
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    safe_VkDisplayPropertiesKHR* local_pProperties = NULL;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (pProperties) {
+            local_pProperties = new safe_VkDisplayPropertiesKHR[*pPropertyCount];
+            for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
+                local_pProperties[idx0].initialize(&pProperties[idx0]);
+                if (pProperties[idx0].display) {
+                    local_pProperties[idx0].display = (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pProperties[idx0].display)];
+                }
+            }
+        }
+    }
+
+    VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, ( VkDisplayPropertiesKHR*)local_pProperties);
+    if (result == VK_SUCCESS && pProperties)
+    {
+        for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
+            std::lock_guard<std::mutex> lock(global_lock);
+
+            uint64_t unique_id = global_unique_id++;
+            my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].display);
+            pProperties[idx0].display = reinterpret_cast<VkDisplayKHR&>(unique_id);
+            pProperties[idx0].displayName = local_pProperties[idx0].displayName;
+            pProperties[idx0].physicalDimensions = local_pProperties[idx0].physicalDimensions;
+            pProperties[idx0].physicalResolution = local_pProperties[idx0].physicalResolution;
+            pProperties[idx0].supportedTransforms = local_pProperties[idx0].supportedTransforms;
+            pProperties[idx0].planeReorderPossible = local_pProperties[idx0].planeReorderPossible;
+            pProperties[idx0].persistentContent = local_pProperties[idx0].persistentContent;
+        }
+    }
+    if (local_pProperties)
+        delete[] local_pProperties;
+    return result;
+}
+
+VkResult explicit_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays)
+{
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
+    if (VK_SUCCESS == result) {
+        if ((*pDisplayCount > 0) && pDisplays) {
+            std::lock_guard<std::mutex> lock(global_lock);
+            for (uint32_t i = 0; i < *pDisplayCount; i++) {
+		    auto it = my_map_data->unique_id_mapping.find(reinterpret_cast<const uint64_t &> (pDisplays[i]));
+                assert (it !=  my_map_data->unique_id_mapping.end());
+                pDisplays[i] = reinterpret_cast<VkDisplayKHR&> (it->second);
+            }
+        }
+    }
+    return result;
+}
+
+
+VkResult explicit_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties)
+{
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    safe_VkDisplayModePropertiesKHR* local_pProperties = NULL;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        display = (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t &>(display)];
+        if (pProperties) {
+            local_pProperties = new safe_VkDisplayModePropertiesKHR[*pPropertyCount];
+            for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
+                local_pProperties[idx0].initialize(&pProperties[idx0]);
+            }
+        }
+    }
+
+    VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, ( VkDisplayModePropertiesKHR*)local_pProperties);
+    if (result == VK_SUCCESS && pProperties)
+    {
+        for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
+            std::lock_guard<std::mutex> lock(global_lock);
+
+            uint64_t unique_id = global_unique_id++;
+            my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].displayMode);
+            pProperties[idx0].displayMode = reinterpret_cast<VkDisplayModeKHR&>(unique_id);
+            pProperties[idx0].parameters.visibleRegion.width = local_pProperties[idx0].parameters.visibleRegion.width;
+            pProperties[idx0].parameters.visibleRegion.height = local_pProperties[idx0].parameters.visibleRegion.height;
+            pProperties[idx0].parameters.refreshRate = local_pProperties[idx0].parameters.refreshRate;
+        }
+    }
+    if (local_pProperties)
+        delete[] local_pProperties;
+    return result;
+}
+#endif
 } // namespace unique_objects
diff --git a/layers/vk_layer_config.cpp b/layers/vk_layer_config.cpp
index d67f405..3f25da6 100644
--- a/layers/vk_layer_config.cpp
+++ b/layers/vk_layer_config.cpp
@@ -19,6 +19,7 @@
  * Author: Jon Ashburn <jon@lunarg.com>
  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
  * Author: Tobin Ehlis <tobin@lunarg.com>
+ * Author: Mark Lobodzinski <mark@lunarg.com>
  **************************************************************************/
 #include <fstream>
 #include <string>
@@ -48,50 +49,10 @@
 
 static ConfigFile g_configFileObj;
 
-static VkLayerDbgAction stringToDbgAction(const char *_enum) {
-    // only handles single enum values
-    if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_IGNORE"))
-        return VK_DBG_LAYER_ACTION_IGNORE;
-    else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_LOG_MSG"))
-        return VK_DBG_LAYER_ACTION_LOG_MSG;
-#ifdef WIN32
-    else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_DEBUG_OUTPUT"))
-        return VK_DBG_LAYER_ACTION_DEBUG_OUTPUT;
-#endif
-    else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_BREAK"))
-        return VK_DBG_LAYER_ACTION_BREAK;
-    return (VkLayerDbgAction)0;
-}
-
-static VkFlags stringToDbgReportFlags(const char *_enum) {
-    // only handles single enum values
-    if (!strcmp(_enum, "VK_DEBUG_REPORT_INFO"))
-        return VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
-    else if (!strcmp(_enum, "VK_DEBUG_REPORT_WARN"))
-        return VK_DEBUG_REPORT_WARNING_BIT_EXT;
-    else if (!strcmp(_enum, "VK_DEBUG_REPORT_PERF_WARN"))
-        return VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
-    else if (!strcmp(_enum, "VK_DEBUG_REPORT_ERROR"))
-        return VK_DEBUG_REPORT_ERROR_BIT_EXT;
-    else if (!strcmp(_enum, "VK_DEBUG_REPORT_DEBUG"))
-        return VK_DEBUG_REPORT_DEBUG_BIT_EXT;
-    return (VkFlags)0;
-}
-
-static unsigned int convertStringEnumVal(const char *_enum) {
-    unsigned int ret;
-
-    ret = stringToDbgAction(_enum);
-    if (ret)
-        return ret;
-
-    return stringToDbgReportFlags(_enum);
-}
-
 const char *getLayerOption(const char *_option) { return g_configFileObj.getOption(_option); }
 
 // If option is NULL or stdout, return stdout, otherwise try to open option
-//  as a filename. If successful, return file handle, otherwise stdout
+// as a filename. If successful, return file handle, otherwise stdout
 FILE *getLayerLogOutput(const char *_option, const char *layerName) {
     FILE *log_output = NULL;
     if (!_option || !strcmp("stdout", _option))
@@ -110,64 +71,80 @@
     return log_output;
 }
 
-VkDebugReportFlagsEXT getLayerOptionFlags(const char *_option, uint32_t optionDefault) {
-    VkDebugReportFlagsEXT flags = optionDefault;
-    const char *option = (g_configFileObj.getOption(_option));
+// Map option strings to flag enum values
+VkFlags GetLayerOptionFlags(std::string _option, std::unordered_map<std::string, VkFlags> const &enum_data,
+                            uint32_t option_default) {
+    VkDebugReportFlagsEXT flags = option_default;
+    std::string option_list = g_configFileObj.getOption(_option.c_str());
 
-    /* parse comma-separated options */
-    while (option) {
-        const char *p = strchr(option, ',');
-        size_t len;
+    while (option_list.length() != 0) {
 
-        if (p)
-            len = p - option;
-        else
-            len = strlen(option);
-
-        if (len > 0) {
-            if (strncmp(option, "warn", len) == 0) {
-                flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
-            } else if (strncmp(option, "info", len) == 0) {
-                flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
-            } else if (strncmp(option, "perf", len) == 0) {
-                flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
-            } else if (strncmp(option, "error", len) == 0) {
-                flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
-            } else if (strncmp(option, "debug", len) == 0) {
-                flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
-            }
+        // Find length of option string
+        std::size_t option_length = option_list.find(",");
+        if (option_length == option_list.npos) {
+            option_length = option_list.size();
         }
 
-        if (!p)
-            break;
+        // Get first option in list
+        const std::string option = option_list.substr(0, option_length);
 
-        option = p + 1;
+        auto enum_value = enum_data.find(option);
+        if (enum_value != enum_data.end()) {
+            flags |= enum_value->second;
+        }
+
+        // Remove first option from option_list
+        option_list.erase(0, option_length);
+        // Remove possible comma separator
+        std::size_t char_position = option_list.find(",");
+        if (char_position == 0) {
+            option_list.erase(char_position, 1);
+        }
+        // Remove possible space
+        char_position = option_list.find(" ");
+        if (char_position == 0) {
+            option_list.erase(char_position, 1);
+        }
     }
     return flags;
 }
 
-bool getLayerOptionEnum(const char *_option, uint32_t *optionDefault) {
-    bool res;
-    const char *option = (g_configFileObj.getOption(_option));
-    if (option != NULL) {
-        *optionDefault = convertStringEnumVal(option);
-        res = false;
-    } else {
-        res = true;
-    }
-    return res;
-}
-
-void setLayerOptionEnum(const char *_option, const char *_valEnum) {
-    unsigned int val = convertStringEnumVal(_valEnum);
-    char strVal[24];
-    snprintf(strVal, 24, "%u", val);
-    g_configFileObj.setOption(_option, strVal);
-}
-
 void setLayerOption(const char *_option, const char *_val) { g_configFileObj.setOption(_option, _val); }
 
-ConfigFile::ConfigFile() : m_fileIsParsed(false) {}
+// Constructor for ConfigFile. Initialize layers to log error messages to stdout by default. If a vk_layer_settings file is present,
+// its settings will override the defaults.
+ConfigFile::ConfigFile() : m_fileIsParsed(false) {
+    m_valueMap["lunarg_core_validation.report_flags"] = "error";
+    m_valueMap["lunarg_image.report_flags"] = "error";
+    m_valueMap["lunarg_object_tracker.report_flags"] = "error";
+    m_valueMap["lunarg_parameter_validation.report_flags"] = "error";
+    m_valueMap["lunarg_swapchain.report_flags"] = "error";
+    m_valueMap["google_threading.report_flags"] = "error";
+
+#ifdef WIN32
+    // For Windows, enable message logging AND OutputDebugString
+    m_valueMap["lunarg_core_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
+    m_valueMap["lunarg_image.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
+    m_valueMap["lunarg_object_tracker.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
+    m_valueMap["lunarg_parameter_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
+    m_valueMap["lunarg_swapchain.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
+    m_valueMap["google_threading.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG,VK_DBG_LAYER_ACTION_DEBUG_OUTPUT";
+#else  // WIN32
+    m_valueMap["lunarg_core_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
+    m_valueMap["lunarg_image.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
+    m_valueMap["lunarg_object_tracker.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
+    m_valueMap["lunarg_parameter_validation.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
+    m_valueMap["lunarg_swapchain.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
+    m_valueMap["google_threading.debug_action"] = "VK_DBG_LAYER_ACTION_DEFAULT,VK_DBG_LAYER_ACTION_LOG_MSG";
+#endif // WIN32
+
+    m_valueMap["lunarg_core_validation.log_filename"] = "stdout";
+    m_valueMap["lunarg_image.log_filename"] = "stdout";
+    m_valueMap["lunarg_object_tracker.log_filename"] = "stdout";
+    m_valueMap["lunarg_parameter_validation.log_filename"] = "stdout";
+    m_valueMap["lunarg_swapchain.log_filename"] = "stdout";
+    m_valueMap["google_threading.log_filename"] = "stdout";
+}
 
 ConfigFile::~ConfigFile() {}
 
@@ -178,7 +155,7 @@
     }
 
     if ((it = m_valueMap.find(_option)) == m_valueMap.end())
-        return NULL;
+        return "";
     else
         return it->second.c_str();
 }
@@ -196,11 +173,12 @@
     char buf[MAX_CHARS_PER_LINE];
 
     m_fileIsParsed = true;
-    m_valueMap.clear();
 
     file.open(filename);
-    if (!file.good())
+    if (!file.good()) {
         return;
+    }
+
 
     // read tokens from the file and form option, value pairs
     file.getline(buf, MAX_CHARS_PER_LINE);
diff --git a/layers/vk_layer_config.h b/layers/vk_layer_config.h
index 92865f6..f64c547 100644
--- a/layers/vk_layer_config.h
+++ b/layers/vk_layer_config.h
@@ -15,9 +15,12 @@
  * limitations under the License.
  *
  * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Mark Lobodzinski <mark@lunarg.com>
  **************************************************************************/
 #pragma once
 #include "vulkan/vulkan.h"
+#include "vulkan/vk_layer.h"
+#include <unordered_map>
 #include <stdbool.h>
 #include <stdio.h>
 
@@ -25,14 +28,42 @@
 extern "C" {
 #endif
 
+// Definitions for Debug Actions
+typedef enum VkLayerDbgActionBits {
+    VK_DBG_LAYER_ACTION_IGNORE = 0x00000000,
+    VK_DBG_LAYER_ACTION_CALLBACK = 0x00000001,
+    VK_DBG_LAYER_ACTION_LOG_MSG = 0x00000002,
+    VK_DBG_LAYER_ACTION_BREAK = 0x00000004,
+    VK_DBG_LAYER_ACTION_DEBUG_OUTPUT = 0x00000008,
+    VK_DBG_LAYER_ACTION_DEFAULT = 0x40000000,
+} VkLayerDbgActionBits;
+typedef VkFlags VkLayerDbgActionFlags;
+
+const std::unordered_map<std::string, VkFlags> debug_actions_option_definitions = {
+    {std::string("VK_DBG_LAYER_ACTION_IGNORE"), VK_DBG_LAYER_ACTION_IGNORE},
+    {std::string("VK_DBG_LAYER_ACTION_CALLBACK"), VK_DBG_LAYER_ACTION_CALLBACK},
+    {std::string("VK_DBG_LAYER_ACTION_LOG_MSG"), VK_DBG_LAYER_ACTION_LOG_MSG},
+    {std::string("VK_DBG_LAYER_ACTION_BREAK"), VK_DBG_LAYER_ACTION_BREAK},
+#if defined(WIN32)
+    {std::string("VK_DBG_LAYER_ACTION_DEBUG_OUTPUT"), VK_DBG_LAYER_ACTION_DEBUG_OUTPUT},
+#endif
+    {std::string("VK_DBG_LAYER_ACTION_DEFAULT"), VK_DBG_LAYER_ACTION_DEFAULT}};
+
+const std::unordered_map<std::string, VkFlags> report_flags_option_definitions = {
+    {std::string("warn"), VK_DEBUG_REPORT_WARNING_BIT_EXT},
+    {std::string("info"), VK_DEBUG_REPORT_INFORMATION_BIT_EXT},
+    {std::string("perf"), VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT},
+    {std::string("error"), VK_DEBUG_REPORT_ERROR_BIT_EXT},
+    {std::string("debug"), VK_DEBUG_REPORT_DEBUG_BIT_EXT}};
+
 const char *getLayerOption(const char *_option);
 FILE *getLayerLogOutput(const char *_option, const char *layerName);
-VkDebugReportFlagsEXT getLayerOptionFlags(const char *_option, uint32_t optionDefault);
-bool getLayerOptionEnum(const char *_option, uint32_t *optionDefault);
+VkFlags GetLayerOptionFlags(std::string _option, std::unordered_map<std::string, VkFlags> const &enum_data,
+                                          uint32_t option_default);
 
 void setLayerOption(const char *_option, const char *_val);
-void setLayerOptionEnum(const char *_option, const char *_valEnum);
 void print_msg_flags(VkFlags msgFlags, char *msg_flags);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/layers/vk_layer_logging.h b/layers/vk_layer_logging.h
index 49470b1..11405e3 100644
--- a/layers/vk_layer_logging.h
+++ b/layers/vk_layer_logging.h
@@ -22,6 +22,7 @@
 #ifndef LAYER_LOGGING_H
 #define LAYER_LOGGING_H
 
+#include "vk_loader_layer.h"
 #include "vk_layer_config.h"
 #include "vk_layer_data.h"
 #include "vk_layer_table.h"
@@ -32,9 +33,11 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <unordered_map>
+#include <vector>
 
 typedef struct _debug_report_data {
-    VkLayerDbgFunctionNode *g_pDbgFunctionHead;
+    VkLayerDbgFunctionNode *debug_callback_list;
+    VkLayerDbgFunctionNode *default_debug_callback_list;
     VkFlags active_flags;
     bool g_DEBUG_REPORT;
 } debug_report_data;
@@ -42,12 +45,78 @@
 template debug_report_data *get_my_data_ptr<debug_report_data>(void *data_key,
                                                                std::unordered_map<void *, debug_report_data *> &data_map);
 
+// Forward Declarations
+static inline bool debug_report_log_msg(const debug_report_data *debug_data, VkFlags msgFlags,
+                                        VkDebugReportObjectTypeEXT objectType, uint64_t srcObject, size_t location, int32_t msgCode,
+                                        const char *pLayerPrefix, const char *pMsg);
+
+// Add a debug message callback node structure to the specified callback linked list
+static inline void AddDebugMessageCallback(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
+                                           VkLayerDbgFunctionNode *new_node) {
+
+    new_node->pNext = *list_head;
+    *list_head = new_node;
+}
+
+// Remove specified debug message callback node structure from the specified callback linked list
+static inline void RemoveDebugMessageCallback(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
+                                              VkDebugReportCallbackEXT callback) {
+    VkLayerDbgFunctionNode *cur_callback = *list_head;
+    VkLayerDbgFunctionNode *prev_callback = cur_callback;
+    bool matched = false;
+
+    debug_data->active_flags = 0;
+    while (cur_callback) {
+        if (cur_callback->msgCallback == callback) {
+            matched = true;
+            prev_callback->pNext = cur_callback->pNext;
+            if (*list_head == cur_callback) {
+                *list_head = cur_callback->pNext;
+            }
+            debug_report_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
+                                 reinterpret_cast<uint64_t &>(cur_callback->msgCallback), 0, VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT,
+                                 "DebugReport", "Destroyed callback");
+        } else {
+            matched = false;
+            debug_data->active_flags |= cur_callback->msgFlags;
+        }
+        prev_callback = cur_callback;
+        cur_callback = cur_callback->pNext;
+        if (matched) {
+            free(prev_callback);
+        }
+    }
+}
+
+// Removes all debug callback function nodes from the specified callback linked lists and frees their resources
+static inline void RemoveAllMessageCallbacks(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head) {
+    VkLayerDbgFunctionNode *current_callback = *list_head;
+    VkLayerDbgFunctionNode *prev_callback = current_callback;
+
+    while (current_callback) {
+        prev_callback = current_callback->pNext;
+        debug_report_log_msg(debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
+                             (uint64_t)current_callback->msgCallback, 0, VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT, "DebugReport",
+                             "Debug Report callbacks not removed before DestroyInstance");
+        free(current_callback);
+        current_callback = prev_callback;
+    }
+    *list_head = NULL;
+}
+
 // Utility function to handle reporting
-static inline bool debug_report_log_msg(const debug_report_data *debug_data, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
-                                        uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix,
-                                        const char *pMsg) {
+static inline bool debug_report_log_msg(const debug_report_data *debug_data, VkFlags msgFlags,
+                                        VkDebugReportObjectTypeEXT objectType, uint64_t srcObject, size_t location, int32_t msgCode,
+                                        const char *pLayerPrefix, const char *pMsg) {
     bool bail = false;
-    VkLayerDbgFunctionNode *pTrav = debug_data->g_pDbgFunctionHead;
+    VkLayerDbgFunctionNode *pTrav = NULL;
+
+    if (debug_data->debug_callback_list != NULL) {
+        pTrav = debug_data->debug_callback_list;
+    } else {
+        pTrav = debug_data->default_debug_callback_list;
+    }
+
     while (pTrav) {
         if (pTrav->msgFlags & msgFlags) {
             if (pTrav->pfnMsgCallback(msgFlags, objectType, srcObject, location, msgCode, pLayerPrefix, pMsg, pTrav->pUserData)) {
@@ -64,20 +133,13 @@
 debug_report_create_instance(VkLayerInstanceDispatchTable *table, VkInstance inst, uint32_t extension_count,
                              const char *const *ppEnabledExtensions) // layer or extension name to be enabled
 {
-    debug_report_data *debug_data;
-    PFN_vkGetInstanceProcAddr gpa = table->GetInstanceProcAddr;
-
-    table->CreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)gpa(inst, "vkCreateDebugReportCallbackEXT");
-    table->DestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)gpa(inst, "vkDestroyDebugReportCallbackEXT");
-    table->DebugReportMessageEXT = (PFN_vkDebugReportMessageEXT)gpa(inst, "vkDebugReportMessageEXT");
-
-    debug_data = (debug_report_data *)malloc(sizeof(debug_report_data));
+    debug_report_data *debug_data = (debug_report_data *)malloc(sizeof(debug_report_data));
     if (!debug_data)
         return NULL;
 
     memset(debug_data, 0, sizeof(debug_report_data));
     for (uint32_t i = 0; i < extension_count; i++) {
-        /* TODO: Check other property fields */
+        // TODO: Check other property fields
         if (strcmp(ppEnabledExtensions[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
             debug_data->g_DEBUG_REPORT = true;
         }
@@ -86,42 +148,32 @@
 }
 
 static inline void layer_debug_report_destroy_instance(debug_report_data *debug_data) {
-    VkLayerDbgFunctionNode *pTrav;
-    VkLayerDbgFunctionNode *pTravNext;
-
-    if (!debug_data) {
-        return;
+    if (debug_data) {
+        RemoveAllMessageCallbacks(debug_data, &debug_data->default_debug_callback_list);
+        RemoveAllMessageCallbacks(debug_data, &debug_data->debug_callback_list);
+        free(debug_data);
     }
-
-    pTrav = debug_data->g_pDbgFunctionHead;
-    /* Clear out any leftover callbacks */
-    while (pTrav) {
-        pTravNext = pTrav->pNext;
-
-        debug_report_log_msg(debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
-                             (uint64_t)pTrav->msgCallback, 0, VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT, "DebugReport",
-                             "Debug Report callbacks not removed before DestroyInstance");
-
-        free(pTrav);
-        pTrav = pTravNext;
-    }
-    debug_data->g_pDbgFunctionHead = NULL;
-
-    free(debug_data);
 }
 
 static inline debug_report_data *layer_debug_report_create_device(debug_report_data *instance_debug_data, VkDevice device) {
-    /* DEBUG_REPORT shares data between Instance and Device,
-     * so just return instance's data pointer */
+    // DEBUG_REPORT shares data between Instance and Device,
+    // so just return instance's data pointer
     return instance_debug_data;
 }
 
-static inline void layer_debug_report_destroy_device(VkDevice device) { /* Nothing to do since we're using instance data record */ }
+static inline void layer_debug_report_destroy_device(VkDevice device) {
+    // Nothing to do since we're using instance data record
+}
 
-static inline VkResult layer_create_msg_callback(debug_report_data *debug_data,
+static inline void layer_destroy_msg_callback(debug_report_data *debug_data, VkDebugReportCallbackEXT callback,
+                                              const VkAllocationCallbacks *pAllocator) {
+    RemoveDebugMessageCallback(debug_data, &debug_data->debug_callback_list, callback);
+    RemoveDebugMessageCallback(debug_data, &debug_data->default_debug_callback_list, callback);
+}
+
+static inline VkResult layer_create_msg_callback(debug_report_data *debug_data, bool default_callback,
                                                  const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
                                                  const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
-    /* TODO: Use app allocator */
     VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
     if (!pNewDbgFuncNode)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -133,9 +185,12 @@
     pNewDbgFuncNode->pfnMsgCallback = pCreateInfo->pfnCallback;
     pNewDbgFuncNode->msgFlags = pCreateInfo->flags;
     pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
-    pNewDbgFuncNode->pNext = debug_data->g_pDbgFunctionHead;
 
-    debug_data->g_pDbgFunctionHead = pNewDbgFuncNode;
+    if (default_callback) {
+        AddDebugMessageCallback(debug_data, &debug_data->default_debug_callback_list, pNewDbgFuncNode);
+    } else {
+        AddDebugMessageCallback(debug_data, &debug_data->debug_callback_list, pNewDbgFuncNode);
+    }
     debug_data->active_flags |= pCreateInfo->flags;
 
     debug_report_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
@@ -143,36 +198,6 @@
     return VK_SUCCESS;
 }
 
-static inline void layer_destroy_msg_callback(debug_report_data *debug_data, VkDebugReportCallbackEXT callback,
-                                              const VkAllocationCallbacks *pAllocator) {
-    VkLayerDbgFunctionNode *pTrav = debug_data->g_pDbgFunctionHead;
-    VkLayerDbgFunctionNode *pPrev = pTrav;
-    bool matched;
-
-    debug_data->active_flags = 0;
-    while (pTrav) {
-        if (pTrav->msgCallback == callback) {
-            matched = true;
-            pPrev->pNext = pTrav->pNext;
-            if (debug_data->g_pDbgFunctionHead == pTrav) {
-                debug_data->g_pDbgFunctionHead = pTrav->pNext;
-            }
-            debug_report_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
-                                 (uint64_t)pTrav->msgCallback, 0, VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT, "DebugReport",
-                                 "Destroyed callback");
-        } else {
-            matched = false;
-            debug_data->active_flags |= pTrav->msgFlags;
-        }
-        pPrev = pTrav;
-        pTrav = pTrav->pNext;
-        if (matched) {
-            /* TODO: Use pAllocator */
-            free(pPrev);
-        }
-    }
-}
-
 static inline PFN_vkVoidFunction debug_report_get_instance_proc_addr(debug_report_data *debug_data, const char *funcName) {
     if (!debug_data || !debug_data->g_DEBUG_REPORT) {
         return NULL;
@@ -253,7 +278,7 @@
                                            VkDebugReportCallbackCreateInfoEXT *infos, VkDebugReportCallbackEXT *callbacks) {
     VkResult rtn = VK_SUCCESS;
     for (uint32_t i = 0; i < num_callbacks; i++) {
-        rtn = layer_create_msg_callback(debug_data, &infos[i], NULL, &callbacks[i]);
+        rtn = layer_create_msg_callback(debug_data, false, &infos[i], NULL, &callbacks[i]);
         if (rtn != VK_SUCCESS) {
             for (uint32_t j = 0; j < i; j++) {
                 layer_destroy_msg_callback(debug_data, callbacks[j], NULL);
@@ -273,14 +298,12 @@
     }
 }
 
-/*
- * Checks if the message will get logged.
- * Allows layer to defer collecting & formating data if the
- * message will be discarded.
- */
+// Checks if the message will get logged.
+// Allows layer to defer collecting & formating data if the
+// message will be discarded.
 static inline bool will_log_msg(debug_report_data *debug_data, VkFlags msgFlags) {
     if (!debug_data || !(debug_data->active_flags & msgFlags)) {
-        /* message is not wanted */
+        // Message is not wanted
         return false;
     }
 
@@ -302,11 +325,9 @@
 }
 #endif
 
-/*
- * Output log message via DEBUG_REPORT
- * Takes format and variable arg list so that output string
- * is only computed if a message needs to be logged
- */
+// Output log message via DEBUG_REPORT
+// Takes format and variable arg list so that output string
+// is only computed if a message needs to be logged
 #ifndef WIN32
 static inline bool log_msg(const debug_report_data *debug_data, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
                            uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *format, ...)
@@ -316,7 +337,7 @@
                            uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *format,
                            ...) {
     if (!debug_data || !(debug_data->active_flags & msgFlags)) {
-        /* message is not wanted */
+        // Message is not wanted
         return false;
     }
 
@@ -324,7 +345,7 @@
     va_start(argptr, format);
     char *str;
     if (-1 == vasprintf(&str, format, argptr)) {
-        /* on failure, glibc vasprintf leaves str undefined */
+        // On failure, glibc vasprintf leaves str undefined
         str = nullptr;
     }
     va_end(argptr);
diff --git a/layers/vk_layer_settings.txt b/layers/vk_layer_settings.txt
index d83b832..c0bc88a 100644
--- a/layers/vk_layer_settings.txt
+++ b/layers/vk_layer_settings.txt
@@ -1,4 +1,5 @@
 # This is an example vk_layer_settings.txt file.
+#
 #  This file allows for per-layer settings which can dynamically affect layer
 #  behavior. Comments in this file are denoted with the "#" char.
 #  Settings lines are of the form "<LayerIdentifier>.<SettingName> = <SettingValue>"
@@ -26,6 +27,9 @@
 #    VK_DBG_LAYER_ACTION_CALLBACK - Call user defined callback function(s) that
 #       have been registered via the VK_EXT_LUNARG_debug_report extension. Since
 #       app must register callback, this is a NOOP for the settings file.
+#    VK_DBG_LAYER_DEBUG_OUTPUT [Windows only] - Log a txt message using the Windows
+#       OutputDebugString function -- messages will show up in Visual Studio output
+#       window, for instance.
 #    VK_DBG_LAYER_ACTION_BREAK - Trigger a breakpoint.
 #
 #   REPORT_FLAGS:
@@ -33,8 +37,9 @@
 #   <LayerIdentifier>.report_flags : This is a comma-delineated list of options telling
 #    the layer what types of messages it should report back. Options are:
 #    info - Report informational messages
-#    warn - Report warnings of using the API in an unrecommended manner which may
-#       also lead to undefined behavior
+#    warn - Report warnings from using the API in a manner which may lead to undefined
+#           behavior or to warn the user of common trouble spots. A warning does NOT
+#           necessarily signify illegal application behavior.
 #    perf - Report using the API in a way that may cause suboptimal performance
 #    error - Report errors in API usage
 #    debug - For layer development. Report messages for debugging layer behavior
@@ -50,10 +55,6 @@
 # Example of actual settings for each layer:
 # ==========================================
 #
-# VK_LAYER_LUNARG_device_limits Settings
-lunarg_device_limits.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG
-lunarg_device_limits.report_flags = error,warn,perf
-lunarg_device_limits.log_filename = stdout
 
 # VK_LAYER_LUNARG_core_validation Settings
 lunarg_core_validation.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG
diff --git a/layers/vk_layer_table.cpp b/layers/vk_layer_table.cpp
index 05e5165..d9ec3c5 100644
--- a/layers/vk_layer_table.cpp
+++ b/layers/vk_layer_table.cpp
@@ -96,7 +96,6 @@
 }
 
 VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void *object) {
-    //    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
     dispatch_key key = get_dispatch_key(object);
     instance_table_map::const_iterator it = map.find((void *)key);
 #if DISPATCH_MAP_DEBUG
diff --git a/layers/vk_layer_utils.cpp b/layers/vk_layer_utils.cpp
index 1c36270..d028ca6 100644
--- a/layers/vk_layer_utils.cpp
+++ b/layers/vk_layer_utils.cpp
@@ -604,11 +604,20 @@
     return result;
 }
 
+// Debug callbacks get created in three ways:
+//   o  Application-defined debug callbacks
+//   o  Through settings in a vk_layer_settings.txt file
+//   o  By default, if neither an app-defined debug callback nor a vk_layer_settings.txt file is present
+//
+// At layer initialization time, default logging callbacks are created to output layer error messages.
+// If a vk_layer_settings.txt file is present its settings will override any default settings.
+//
+// If a vk_layer_settings.txt file is present and an application defines a debug callback, both callbacks
+// will be active.  If no vk_layer_settings.txt file is present, creating an application-defined debug
+// callback will cause the default callbacks to be unregisterd and removed.
 void layer_debug_actions(debug_report_data *report_data, std::vector<VkDebugReportCallbackEXT> &logging_callback,
-                      const VkAllocationCallbacks *pAllocator, const char *layer_identifier) {
+                         const VkAllocationCallbacks *pAllocator, const char *layer_identifier) {
 
-    uint32_t report_flags = 0;
-    uint32_t debug_action = 0;
     VkDebugReportCallbackEXT callback = VK_NULL_HANDLE;
 
     std::string report_flags_key = layer_identifier;
@@ -618,9 +627,11 @@
     debug_action_key.append(".debug_action");
     log_filename_key.append(".log_filename");
 
-    // initialize layer options
-    report_flags = getLayerOptionFlags(report_flags_key.c_str(), 0);
-    getLayerOptionEnum(debug_action_key.c_str(), (uint32_t *)&debug_action);
+    // Initialize layer options
+    VkDebugReportFlagsEXT report_flags = GetLayerOptionFlags(report_flags_key, report_flags_option_definitions, 0);
+    VkLayerDbgActionFlags debug_action = GetLayerOptionFlags(debug_action_key, debug_actions_option_definitions, 0);
+    // Flag as default if these settings are not from a vk_layer_settings.txt file
+    bool default_layer_callback = (debug_action & VK_DBG_LAYER_ACTION_DEFAULT) ? true : false;
 
     if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
         const char *log_filename = getLayerOption(log_filename_key.c_str());
@@ -631,10 +642,12 @@
         dbgCreateInfo.flags = report_flags;
         dbgCreateInfo.pfnCallback = log_callback;
         dbgCreateInfo.pUserData = (void *)log_output;
-        layer_create_msg_callback(report_data, &dbgCreateInfo, pAllocator, &callback);
+        layer_create_msg_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &callback);
         logging_callback.push_back(callback);
     }
 
+    callback = VK_NULL_HANDLE;
+
     if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
         VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
         memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
@@ -642,7 +655,7 @@
         dbgCreateInfo.flags = report_flags;
         dbgCreateInfo.pfnCallback = win32_debug_output_msg;
         dbgCreateInfo.pUserData = NULL;
-        layer_create_msg_callback(report_data, &dbgCreateInfo, pAllocator, &callback);
+        layer_create_msg_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &callback);
         logging_callback.push_back(callback);
     }
 }
diff --git a/layers/vk_validation_layer_details.md b/layers/vk_validation_layer_details.md
index dd6139e..4b62a2e 100644
--- a/layers/vk_validation_layer_details.md
+++ b/layers/vk_validation_layer_details.md
@@ -6,17 +6,18 @@
 
 ### VK_LAYER_LUNARG_standard_validation Overview
 
-This is a meta-layer managed by the loader. Specifying this layer name will cause the loader to load the all of the standard validation layers in the following optimal order:
+This is a meta-layer managed by the loader. On desktop systems, specifying this layer name will cause the loader to load the all of the standard validation layers in the following optimal order:
 
  - VK_LAYER_GOOGLE_threading
  - VK_LAYER_LUNARG_parameter_validation
- - VK_LAYER_LUNARG_device_limits
  - VK_LAYER_LUNARG_object_tracker
  - VK_LAYER_LUNARG_image
  - VK_LAYER_LUNARG_core_validation
  - VK_LAYER_LUNARG_swapchain
  - VK_LAYER_GOOGLE_unique_objects
 
+For platforms not using the standard loader (i.e., mobile platforms) the layers should be declared explicitly in the order shown above.
+
 Other layers can be specified and the loader will remove duplicates. See the following individual layer descriptions for layer details.
 
 ## VK_LAYER_LUNARG_core_validation
@@ -32,81 +33,82 @@
 | ----- | -------- | ---------------- | ------------ | -------- | ---------- |
 | Valid Pipeline Layouts | Verify that sets being bound are compatible with their PipelineLayout and that the last-bound PSO PipelineLayout at Draw time is compatible with all bound sets used by that PSO | PIPELINE_LAYOUTS_INCOMPATIBLE | vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DescriptorSetCompatibility | None |
 | Valid BeginCommandBuffer state | Must not call Begin on command buffers that are being recorded, and primary command buffers must specify VK_NULL_HANDLE for RenderPass or Framebuffer parameters, while secondary command buffers must provide non-null parameters,  | BEGIN_CB_INVALID_STATE | vkBeginCommandBuffer | CallBeginCommandBufferBeforeCompletion SecondaryCommandBufferNullRenderpass | None |
-| Command Buffer Simultaneous Use | Violation of VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT rules. Most likely attempting to simultaneously use a CmdBuffer w/o having that bit set. This also warns if you add secondary command buffer w/o that bit set to a primary command buffer that does have that bit set. | INVALID_CB_SIMULTANEOUS_USE | vkQueueSubmit vkCmdExecuteCommands | TODO | Write test |
+| Command Buffer Simultaneous Use | Violation of VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT rules. Most likely attempting to simultaneously use a CmdBuffer w/o having that bit set. This also warns if you add secondary command buffer w/o that bit set to a primary command buffer that does have that bit set. | INVALID_CB_SIMULTANEOUS_USE | vkQueueSubmit vkCmdExecuteCommands | CommandBufferTwoSubmits | TODO - Missing tests for 2 cases of this check, both in CmdExecuteCommands() |
 | Valid Command Buffer Reset | Can only reset individual command buffer that was allocated from a pool with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set | INVALID_COMMAND_BUFFER_RESET | vkBeginCommandBuffer vkResetCommandBuffer | CommandBufferResetErrors | None |
 | PSO Bound | Verify that a properly created and valid pipeline object is bound to the CommandBuffer specified in these calls | NO_PIPELINE_BOUND | vkCmdBindDescriptorSets vkCmdBindVertexBuffers | PipelineNotBound | This check is currently more related to VK_LAYER_LUNARG_core_validation internal data structures and less about verifying that PSO is bound at all appropriate points in API. For API purposes, need to make sure this is checked at Draw time and any other relevant calls. |
-| Valid DescriptorPool | Verifies that the descriptor set pool object was properly created and is valid | INVALID_POOL | vkResetDescriptorPool vkAllocateDescriptorSets | TODO | This is just an internal layer data structure check. VK_LAYER_LUNARG_parameter_validation or VK_LAYER_LUNARG_object_tracker should really catch bad DSPool |
-| Valid DescriptorSet | Validate that descriptor set was properly created and is currently valid | INVALID_SET | vkCmdBindDescriptorSets | TODO | Is this needed other places (like Update/Clear descriptors) |
-| Valid DescriptorSetLayout | Flag DescriptorSetLayout object that was not properly created | INVALID_LAYOUT | vkAllocateDescriptorSets | TODO | Anywhere else to check this? |
+| Valid DescriptorSet | Validate that descriptor set was properly created and is currently valid | INVALID_SET | vkCmdBindDescriptorSets | InvalidDescriptorSet | Is this needed other places (like Update/Clear descriptors) |
+| Valid DescriptorSetLayout | Flag DescriptorSetLayout object that was not properly created | INVALID_LAYOUT | vkAllocateDescriptorSets | InvalidDescriptorSetLayout | Anywhere else to check this? |
 | Valid RenderArea | Flag renderArea field that is outside of the framebuffer | INVALID_RENDER_AREA | vkCmdBeginRenderPass | TODO | Anywhere else to check this? |
 | Valid Pipeline | Flag VkPipeline object that was not properly created, or case when Draw/Dispatch is bound to cmd buffer without a pipeline being bound | INVALID_PIPELINE | vkCmdBindPipeline | InvalidPipeline | NA |
-| Valid PipelineLayout | Flag VkPipelineLayout object that was not properly created | INVALID_PIPELINE_LAYOUT | vkCmdBindPipeline | TODO | Write test for this case |
 | Valid Pipeline Create Info | Tests for the following: That compute shaders are not specified for the graphics pipeline, tess evaluation and tess control shaders are included or excluded as a pair, that VK_PRIMITIVE_TOPOLOGY_PATCH_LIST is set as IA topology for tessellation pipelines, that VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive topology is only set for tessellation pipelines, and that Vtx Shader specified | INVALID_PIPELINE_CREATE_STATE | vkCreateGraphicsPipelines | InvalidPipelineCreateState | NA |
-| Valid CommandBuffer | Validates that the command buffer object was properly created and is currently valid | INVALID_COMMAND_BUFFER | vkQueueSubmit vkBeginCommandBuffer vkEndCommandBuffer vkCmdBindPipeline vkCmdBindDescriptorSets vkCmdBindIndexBuffer vkCmdBindVertexBuffers vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatch vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearAttachments vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkCmdSetEvent vkCmdResetEvent vkCmdWaitEvents vkCmdPipelineBarrier vkCmdBeginQuery vkCmdEndQuery vkCmdResetQueryPool vkCmdWriteTimestamp vkCmdBeginRenderPass vkCmdNextSubpass vkCmdEndRenderPass vkCmdExecuteCommands vkAllocateCommandBuffers | TODO | NA |
+| Valid CommandBuffer | Validates that the command buffer object was properly created and is currently valid | INVALID_COMMAND_BUFFER | vkQueueSubmit vkBeginCommandBuffer vkEndCommandBuffer vkCmdBindPipeline vkCmdBindDescriptorSets vkCmdBindIndexBuffer vkCmdBindVertexBuffers vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatch vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearAttachments vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkCmdSetEvent vkCmdResetEvent vkCmdWaitEvents vkCmdPipelineBarrier vkCmdBeginQuery vkCmdEndQuery vkCmdResetQueryPool vkCmdWriteTimestamp vkCmdBeginRenderPass vkCmdNextSubpass vkCmdEndRenderPass vkCmdExecuteCommands vkAllocateCommandBuffers | InvalidCmdBufferBufferDestroyed InvalidCmdBufferImageDestroyed InvalidCmdBufferEventDestroyed InvalidCmdBufferQueryPoolDestroyed InvalidCmdBufferPipelineDestroyed ExecuteCommandsPrimaryCB | TODO - missing tests for 8 separate cases where this error is flagged. Cases are getCBNode(), 1st case in validateCmdsInCmdBuffer(), checkGraphicsBit(), checkComputeBit(), checkGraphicsOrComputeBit(), BeginCommandBuffer(), validatePrimaryCommandBuffer() and CmdExecuteCommands() |
 | Vtx Buffer Bounds | Check if VBO index too large for PSO Vtx binding count, and that at least one vertex buffer is attached to pipeline object | VTX_INDEX_OUT_OF_BOUNDS | vkCmdBindDescriptorSets vkCmdBindVertexBuffers | VtxBufferBadIndex | NA |
 | Idx Buffer Alignment | Verify that offset of Index buffer falls on an alignment boundary as defined by IdxBufferAlignmentError param | VTX_INDEX_ALIGNMENT_ERROR | vkCmdBindIndexBuffer | IdxBufferAlignmentError | NA |
 | Cmd Buffer End | Verifies that EndCommandBuffer was called for this commandBuffer at QueueSubmit time | NO_END_COMMAND_BUFFER | vkQueueSubmit | TODO | NA |
 | Cmd Buffer Begin | Check that BeginCommandBuffer was called for this command buffer when binding commands or calling end | NO_BEGIN_COMMAND_BUFFER | vkEndCommandBuffer vkCmdBindPipeline vkCmdSetViewport vkCmdSetLineWidth vkCmdSetDepthBias vkCmdSetBlendConstants vkCmdSetDepthBounds vkCmdSetStencilCompareMask vkCmdSetStencilWriteMask vkCmdSetStencilReference vkCmdBindDescriptorSets vkCmdBindIndexBuffer vkCmdBindVertexBuffers vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatch vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearAttachments vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkCmdSetEvent vkCmdResetEvent vkCmdWaitEvents vkCmdPipelineBarrier vkCmdBeginQuery vkCmdEndQuery vkCmdResetQueryPool vkCmdWriteTimestamp | NoBeginCommandBuffer | NA |
 | Cmd Buffer Submit Count | Verify that ONE_TIME submit cmdbuffer is not submitted multiple times | COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION | vkBeginCommandBuffer, vkQueueSubmit | CommandBufferTwoSubmits | NA |
 | Valid Secondary CommandBuffer | Validates that no primary command buffers are sent to vkCmdExecuteCommands() are | INVALID_SECONDARY_COMMAND_BUFFER | vkCmdExecuteCommands | ExecuteCommandsPrimaryCB | NA |
-| Invalid Descriptor Set | Invalid Descriptor Set used. Either never created or already destroyed. | INVALID_DESCRIPTOR_SET | vkQueueSubmit | TODO | Create Test |
+| Invalid Descriptor Set | Invalid Descriptor Set used. Either never created or already destroyed. | INVALID_DESCRIPTOR_SET | vkQueueSubmit vkUpdateDescriptorSets | TODO | Create Tests as needed. Should also cross-check with object_tracker to see if any of these cases can be removed as redundant |
 | Descriptor Type | Verify Descriptor type in bound descriptor set layout matches descriptor type specified in update. This also includes mismatches in the TYPES of copied descriptors. | DESCRIPTOR_TYPE_MISMATCH | vkUpdateDescriptorSets | DSTypeMismatch CopyDescriptorUpdateErrors | NA |
-| Descriptor StageFlags | Verify all descriptors within a single write update have the same stageFlags | DESCRIPTOR_STAGEFLAGS_MISMATCH | vkUpdateDescriptorSets | TODO | Test this case |
+| Descriptor StageFlags | Verify all descriptors within a single write update have the same stageFlags | DESCRIPTOR_STAGEFLAGS_MISMATCH | vkUpdateDescriptorSets | WriteDescriptorSetIntegrityCheck |  |
 | DS Update Size | DS update out of bounds for given layout section. | DESCRIPTOR_UPDATE_OUT_OF_BOUNDS | vkUpdateDescriptorSets | DSUpdateOutOfBounds CopyDescriptorUpdateErrors | NA |
 | Descriptor Pool empty | Attempt to allocate descriptor type from descriptor pool when no more of that type are available to be allocated. | DESCRIPTOR_POOL_EMPTY | vkAllocateDescriptorSets | AllocDescriptorFromEmptyPool | NA |
-| Free from NON_FREE Pool | It's invalid to call vkFreeDescriptorSets() on Sets that were allocated from a Pool created with NON_FREE usage. | CANT_FREE_FROM_NON_FREE_POOL | vkFreeDescriptorSets | TODO | NA |
-| DS Update Index | DS update binding too large for layout binding count. | INVALID_UPDATE_INDEX | vkUpdateDescriptorSets | InvalidDSUpdateIndex CopyDescriptorUpdateErrors | NA |
+| Free from NON_FREE Pool | It's invalid to call vkFreeDescriptorSets() on Sets that were allocated from a Pool created with NON_FREE usage. | CANT_FREE_FROM_NON_FREE_POOL | vkFreeDescriptorSets | FreeDescriptorFromOneShotPool | NA |
+| DS Write Update | DS write update with invalid state which includes things like bad update objects, bad update sizes, and bad descriptor binding values. | INVALID_WRITE_UPDATE | vkUpdateDescriptorSets | InvalidDSUpdateIndex CopyDescriptorUpdateErrors DSUsageBitsErrors DSAspectBitsErrors DSBufferInfoErrors | NA |
+| DS Copy Update | DS copy update with invalid state such as bad object state, mis-matched descriptor types or a bad binding index. | INVALID_COPY_UPDATE | vkUpdateDescriptorSets | InvalidDSUpdateIndex CopyDescriptorUpdateErrors DSUsageBitsErrors DSAspectBitsErrors | NA |
 | DS Update Type | Verifies that structs in DS Update tree are properly created, currently valid, and of the right type | INVALID_UPDATE_STRUCT | vkUpdateDescriptorSets | InvalidDSUpdateStruct | NA |
 | MSAA Sample Count | Verifies that Pipeline, RenderPass, and Subpass sample counts are consistent | NUM_SAMPLES_MISMATCH | vkCmdBindPipeline vkCmdBeginRenderPass vkCmdNextSubpass | NumSamplesMismatch | NA |
-| Dynamic Viewport State Binding | Verify that viewport dynamic state bound to Cmd Buffer at Draw time | VIEWPORT_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicStatesNotBound | NA |
-| Dynamic Scissor State Binding | Verify that scissor dynamic state bound to Cmd Buffer at Draw time | SCISSOR_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicStatesNotBound | NA |
-| Dynamic Line Width State Binding | Verify that line width dynamic state bound to Cmd Buffer at draw time when required | LINE_WIDTH_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicStatesNotBound | NA |
-| Dynamic Depth Bias State Binding | Verify that depth bias dynamic state bound when depth enabled | DEPTH_BIAS_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicStatesNotBound | NA |
-| Dynamic Blend State Binding | Verify that blend dynamic state bound when color blend enabled | BLEND_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicStatesNotBound | NA |
-| Dynamic Depth Bounds State Binding | Verify that depth bounds dynamic state bound when depth enabled | DEPTH_BOUNDS_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicStatesNotBound | NA |
-| Dynamic Stencil State Binding | Verify that stencil dynamic state bound when depth enabled | STENCIL_NOT_BOUND | vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicStatesNotBound | NA |
+| Dynamic Viewport State Binding | Verify that viewport dynamic state bound to Cmd Buffer at Draw time | VIEWPORT_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicViewportNotBound | NA |
+| Dynamic Scissor State Binding | Verify that scissor dynamic state bound to Cmd Buffer at Draw time | SCISSOR_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicScissorNotBound | NA |
+| Dynamic Line Width State Binding | Verify that line width dynamic state bound to Cmd Buffer at draw time when required | LINE_WIDTH_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicLineWidthNotBound | NA |
+| Dynamic Depth Bias State Binding | Verify that depth bias dynamic state bound when depth enabled | DEPTH_BIAS_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicDepthBiasNotBound | NA |
+| Dynamic Blend State Binding | Verify that blend dynamic state bound when color blend enabled | BLEND_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamiBlendConstantsNotBound | NA |
+| Dynamic Depth Bounds State Binding | Verify that depth bounds dynamic state bound when depth enabled | DEPTH_BOUNDS_NOT_BOUND |vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicDepthBoundsNotBound | NA |
+| Dynamic Stencil State Binding | Verify that stencil dynamic state bound when depth enabled | STENCIL_NOT_BOUND | vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DynamicStencilReadNotBound DynamicStencilWriteNotBound DynamicStencilRefNotBound | NA |
 | RenderPass misuse | Tests for the following: that vkCmdDispatch, vkCmdDispatchIndirect, vkCmdCopyBuffer, vkCmdCopyImage, vkCmdBlitImage, vkCmdCopyBufferToImage, vkCmdCopyImageToBuffer, vkCmdUpdateBuffer, vkCmdFillBuffer, vkCmdClearColorImage, vkCmdClearDepthStencilImage, vkCmdResolveImage, vkCmdSetEvent, vkCmdResetEvent, vkCmdResetQueryPool, vkCmdCopyQueryPoolResults, vkCmdBeginRenderPass, vkEndCommandBuffer are not called during an active Renderpass, and that binding compute descriptor sets or pipelines does not take place during an active Renderpass  | INVALID_RENDERPASS_CMD | vkCmdBindPipeline vkCmdBindDescriptorSets vkCmdDispatch vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkCmdSetEvent vkCmdResetEvent vkCmdResetQueryPool vkCmdCopyQueryPoolResults vkCmdBeginRenderPass vkEndCommandBuffer | RenderPassWithinRenderPass UpdateBufferWithinRenderPass ClearColorImageWithinRenderPass ClearDepthStencilImageWithinRenderPass FillBufferWithinRenderPass EndCommandBufferWithinRenderPass | NA |
 | Correct use of RenderPass | Validates that the following rendering commands are issued inside an active RenderPass: vkCmdDraw, vkCmdDrawIndexed, vkCmdDrawIndirect, vkCmdDrawIndexedIndirect, vkCmdClearAttachments, vkCmdNextSubpass, vkCmdEndRenderPass | NO_ACTIVE_RENDERPASS | vkCmdBindPipeline vkCmdBindDescriptorSets  vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdClearAttachments vkCmdNextSubpass vkCmdEndRenderPass | ClearColorAttachmentsOutsideRenderPass | NA |
 | Valid RenderPass | Flag error if attempt made to Begin/End/Continue a NULL or otherwise invalid RenderPass object | INVALID_RENDERPASS | vkCmdBeginRenderPass vkCmdEndRenderPass vkBeginCommandBuffer | NullRenderPass | NA |
-| RenderPass Compatibility | Verify that active renderpass is compatible with renderpass specified in secondary command buffer, and that renderpass specified for a framebuffer is compatible with renderpass specified in secondary command buffer | RENDERPASS_INCOMPATIBLE | vkCmdExecuteCommands vkBeginCommandBuffer | TODO | None |
-| Framebuffer Compatibility | If a framebuffer is passed to secondary command buffer in vkBeginCommandBuffer, then it must match active renderpass (if any) at time of vkCmdExecuteCommands | FRAMEBUFFER_INCOMPATIBLE | vkCmdExecuteCommands | TODO | None |
+| RenderPass Compatibility | Verify that active renderpass is compatible with renderpass specified in secondary command buffer, and that renderpass specified for a framebuffer is compatible with renderpass specified in secondary command buffer. Also that parameters for BeginRenderpass are compatible with actual renderpass. | RENDERPASS_INCOMPATIBLE | vkCmdExecuteCommands vkBeginCommandBuffer vkCmdBeginRenderPass vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | RenderPassClearOpMismatch RenderPassIncompatible FramebufferCreateErrors | Need to write some more tests to cover all of these cases. |
+| Framebuffer Compatibility | If a framebuffer is passed to secondary command buffer in vkBeginCommandBuffer, then it must match active renderpass (if any) at time of vkCmdExecuteCommands | FRAMEBUFFER_INCOMPATIBLE | vkCmdExecuteCommands | FramebufferIncompatible | None |
+| Framebuffer Creation | If a CreateFramebuffer is called with invalide CreateInfo such as attachments with bad mip levelCount or dimensions | INVALID_FRAMEBUFFER_CREATE_INFO | vkCreateFramebuffer | FramebufferCreateErrors | None |
 | DescriptorSet Updated | Warn user if DescriptorSet bound that was never updated and is not empty. Trigger error at draw time if a set being used was never updated. | DESCRIPTOR_SET_NOT_UPDATED | vkCmdBindDescriptorSets vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | DescriptorSetCompatibility | NA |
 | DescriptorSet Bound | Error if DescriptorSet not bound that is used by currently bound VkPipeline at draw time | DESCRIPTOR_SET_NOT_BOUND | vkCmdBindDescriptorSets | DescriptorSetNotUpdated | NA |
 | Dynamic Offset Count | Error if dynamicOffsetCount at CmdBindDescriptorSets time is not equal to the actual number of dynamic descriptors in all sets being bound. | INVALID_DYNAMIC_OFFSET_COUNT | vkCmdBindDescriptorSets | InvalidDynamicOffsetCases | None |
 | Dynamic Offsets | At draw time, for a *_DYNAMIC type descriptor, the combination of dynamicOffset along with offset and range from its descriptor update must be less than the size of its buffer. | DYNAMIC_OFFSET_OVERFLOW | vkCmdDraw vkCmdDrawIndexed vkCmdDrawIndirect vkCmdDrawIndexedIndirect | InvalidDynamicOffsetCases | None |
 | Correct Clear Use | Warn user if CmdClear for Color or DepthStencil issued to Cmd Buffer prior to a Draw Cmd. RenderPass LOAD_OP_CLEAR is preferred in this case. | CLEAR_CMD_BEFORE_DRAW | vkCmdClearColorImage vkCmdClearDepthStencilImage | ClearCmdNoDraw | NA |
-| Index Buffer Binding | Verify that an index buffer is bound at the point when an indexed draw is attempted. | INDEX_BUFFER_NOT_BOUND | vkCmdDrawIndexed vkCmdDrawIndexedIndirect | TODO | Implement validation test |
-| Viewport and Scissors match | In PSO viewportCount and scissorCount must match. Also for each count that is non-zero, there corresponding data array ptr should be non-NULL. | VIEWPORT_SCISSOR_MISMATCH | vkCreateGraphicsPipelines vkCmdSetViewport vkCmdSetScissor | TODO | Implement validation test |
+| Index Buffer Binding | Verify that an index buffer is bound at the point when an indexed draw is attempted. | INDEX_BUFFER_NOT_BOUND | vkCmdDrawIndexed vkCmdDrawIndexedIndirect | IndexBufferNotBound | NA |
+| Viewport and Scissors match | In PSO viewportCount and scissorCount must match. Also for each count that is non-zero, there corresponding data array ptr should be non-NULL. | VIEWPORT_SCISSOR_MISMATCH | vkCreateGraphicsPipelines vkCmdSetViewport vkCmdSetScissor | PSOViewportStateNotSet PSOViewportScissorCountMismatch PSOViewportCountWithoutDataAndDynScissorMismatch PSOScissorCountWithoutDataAndDynViewportMismatch | NA |
 | Valid Image Aspects for descriptor Updates | When updating ImageView for Descriptor Sets with layout of DEPTH_STENCIL type, the Image Aspect must not have both the DEPTH and STENCIL aspects set, but must have one of the two set. For COLOR_ATTACHMENT, aspect must have COLOR_BIT set. | INVALID_IMAGE_ASPECT | vkUpdateDescriptorSets | DepthStencilImageViewWithColorAspectBitError | This test hits Image layer error, but tough to create case that that skips that error and gets to VK_LAYER_LUNARG_core_validaton draw state error. |
 | Valid sampler descriptor Updates | An invalid sampler is used when updating SAMPLER descriptor. | SAMPLER_DESCRIPTOR_ERROR | vkUpdateDescriptorSets | SampleDescriptorUpdateError | Currently only making sure sampler handle is known, can add further validation for sampler parameters |
-| Immutable sampler update consistency | Within a single write update, all sampler updates must use either immutable samplers or non-immutable samplers, but not a combination of both. | INCONSISTENT_IMMUTABLE_SAMPLER_UPDATE | vkUpdateDescriptorSets | TODO | Write a test for this case |
+| Immutable sampler update consistency | Within a single write update, all sampler updates must use either immutable samplers or non-immutable samplers, but not a combination of both. | INCONSISTENT_IMMUTABLE_SAMPLER_UPDATE | vkUpdateDescriptorSets | WriteDescriptorSetIntegrityCheck | |
 | Valid imageView descriptor Updates | An invalid imageView is used when updating *_IMAGE or *_ATTACHMENT descriptor. | IMAGEVIEW_DESCRIPTOR_ERROR | vkUpdateDescriptorSets | ImageViewDescriptorUpdateError | Currently only making sure imageView handle is known, can add further validation for imageView and underlying image parameters |
 | Valid bufferView descriptor Updates | An invalid bufferView is used when updating *_TEXEL_BUFFER descriptor. | BUFFERVIEW_DESCRIPTOR_ERROR | vkUpdateDescriptorSets | InvalidBufferViewObject | Currently only making sure bufferView handle is known, can add further validation for bufferView parameters |
-| Valid bufferInfo descriptor Updates | An invalid bufferInfo is used when updating *_UNIFORM_BUFFER* or *_STORAGE_BUFFER* descriptor. | BUFFERINFO_DESCRIPTOR_ERROR | vkUpdateDescriptorSets | TODO | Implement validation test |
-| Attachment References in Subpass | Attachment reference must be present in active subpass | MISSING_ATTACHMENT_REFERENCE | vkCmdClearAttachments | TODO | Currently only making sure bufferInfo has buffer whose handle is known, can add further validation for bufferInfo parameters |
+| Valid bufferInfo descriptor Updates | An invalid bufferInfo is used when updating *_UNIFORM_BUFFER* or *_STORAGE_BUFFER* descriptor. | BUFFERINFO_DESCRIPTOR_ERROR | vkUpdateDescriptorSets | WriteDescriptorSetIntegrityCheck | |
+| Attachment References in Subpass | Attachment reference must be present in active subpass | MISSING_ATTACHMENT_REFERENCE | vkCmdClearAttachments | MissingClearAttachment | Currently only making sure bufferInfo has buffer whose handle is known, can add further validation for bufferInfo parameters |
 | Verify Image Layouts | Validate correct image layouts for presents, image transitions, command buffers and renderpasses | INVALID_IMAGE_LAYOUT | vkCreateRenderPass vkMapMemory vkQueuePresentKHR vkQueueSubmit vkCmdCopyImage vkCmdCopyImageToBuffer vkCmdWaitEvents VkCmdPipelineBarrier | InvalidImageLayout MapMemWithoutHostVisibleBit | None |
 | Verify Memory Access Flags/Memory Barriers | Validate correct access flags for memory barriers | INVALID_BARRIER | vkCmdWaitEvents vkCmdPipelineBarrier | InvalidBarriers | None |
-| Verify Memory Buffer Not Deleted | Validate Command Buffer not submitted with deleted memory buffer | INVALID_BUFFER | vkQueueSubmit | TODO | None |
-| Verify Memory Buffer Destroy | Validate memory buffers are not destroyed more than once | DOUBLE_DESTROY | vkDestroyBuffer | TODO | None |
-| Verify Object Not In Use | Validate that object being freed or modified is not in use | OBJECT_INUSE | vkDestroyBuffer vkFreeDescriptorSets vkUpdateDescriptorSets | TODO | None |
-| Verify Get Queries| Validate that that queries are properly setup, initialized and synchronized | INVALID_QUERY | vkGetFenceStatus vkQueueWaitIdle vkWaitForFences vkDeviceWaitIdle vkCmdBeginQuery vkCmdEndQuery | TODO | None |
-| Verify Fences Not In Use | Validate that that fences are not used in multiple submit calls at the same time | INVALID_FENCE | vkQueueSubmit | TODO | None |
-| Verify Semaphores Not In Use | Validate that the semaphores are not used in multiple submit calls at the same time | INVALID_SEMAPHORE | vkQueueSubmit | TODO | None |
+| Verify Memory Buffer Not Deleted | Validate Command Buffer not submitted with deleted memory buffer | INVALID_BUFFER | vkQueueSubmit | VertexBufferInvalid | None |
+| Verify Memory Buffer Destroy | Validate memory buffers are not destroyed more than once | DOUBLE_DESTROY | vkDestroyBuffer | VertexBufferInvalid | None |
+| Verify Object Not In Use | Validate that object being freed or modified is not in use | OBJECT_INUSE | vkDestroyBuffer vkFreeDescriptorSets vkUpdateDescriptorSets vkDestroySemaphore | TODO | Write tests for these cases, currently 3 cases, 1 in validateIdleDescriptorSet(), 1 in validateIdleBuffer(), 1 in DestroySemaphore() |
+| Verify Get Queries| Validate that that queries are properly setup, initialized and synchronized | INVALID_QUERY | vkGetFenceStatus vkQueueWaitIdle vkWaitForFences vkDeviceWaitIdle vkCmdBeginQuery vkCmdEndQuery | TODO | Need to check existing case against object_tracker and remove any redundant checks. Then write tests for remaining case. Currently there are 8 cases for this check with 1 each in cleanInFlightCmdBuffer(), EndCommandBuffer(), CmdEndQuery(), validateQuery(), and 4 cases in GetQueryPoolResults() |
+| Verify Fences Not In Use | Validate that that fences are not used in multiple submit calls at the same time | INVALID_FENCE | vkQueueSubmit | TODO | Currently 3 cases of this check to be tested, 1 each in ValidateFenceForSubmit(), DestroyFence(), and ResetFences() |
 | Verify Events Not In Use | Validate that that events are not used at the time they are destroyed | INVALID_EVENT | vkDestroyEvent | TODO | None |
 | Live Semaphore  | When waiting on a semaphore, need to make sure that the semaphore is live and therefore can be signalled, otherwise queue is stalled and cannot make forward progress. | QUEUE_FORWARD_PROGRESS | vkQueueSubmit vkQueueBindSparse vkQueuePresentKHR vkAcquireNextImageKHR | TODO | Create test |
-| Buffer Alignment  | Buffer memory offset in BindBufferMemory must agree with VkMemoryRequirements::alignment returned from a call to vkGetBufferMemoryRequirements with buffer | INVALID_BUFFER_MEMORY_OFFSET | vkBindBufferMemory | TODO | Create test |
-| Texel Buffer Alignment  | Storage/Uniform Texel Buffer memory offset in BindBufferMemory must agree with offset alignment device limit | INVALID_TEXEL_BUFFER_OFFSET | vkBindBufferMemory | TODO | Create test |
-| Storage Buffer Alignment  | Storage Buffer offsets in BindBufferMemory, BindDescriptorSets must agree with offset alignment device limit | INVALID_STORAGE_BUFFER_OFFSET | vkBindBufferMemory vkCmdBindDescriptorSets | TODO | Create test |
-| Uniform Buffer Alignment  | Uniform Buffer offsets in BindBufferMemory, BindDescriptorSets must agree with offset alignment device limit | INVALID_UNIFORM_BUFFER_OFFSET | vkBindBufferMemory vkCmdBindDescriptorSets | TODO | Create test |
+| Buffer Alignment  | Buffer memory offset in BindBufferMemory must agree with VkMemoryRequirements::alignment returned from a call to vkGetBufferMemoryRequirements with buffer | INVALID_BUFFER_MEMORY_OFFSET | vkBindBufferMemory | VertexBufferInvalid | None |
+| Texel Buffer Alignment  | Storage/Uniform Texel Buffer memory offset in BindBufferMemory must agree with offset alignment device limit | INVALID_TEXEL_BUFFER_OFFSET | vkBindBufferMemory | VertexBufferInvalid | None |
+| Storage Buffer Alignment  | Storage Buffer offsets in BindBufferMemory, BindDescriptorSets must agree with offset alignment device limit | INVALID_STORAGE_BUFFER_OFFSET | vkBindBufferMemory vkCmdBindDescriptorSets | VertexBufferInvalid | None |
+| Uniform Buffer Alignment  | Uniform Buffer offsets in BindBufferMemory, BindDescriptorSets must agree with offset alignment device limit | INVALID_UNIFORM_BUFFER_OFFSET | vkBindBufferMemory vkCmdBindDescriptorSets | VertexBufferInvalid | None |
 | Independent Blending  | If independent blending is not enabled, all elements of pAttachments must be identical | INDEPENDENT_BLEND | vkCreateGraphicsPipelines | TODO | Create test |
-| Enabled Logic Operations  | If logic operations is not enabled, logicOpEnable must be VK_FALSE | DISABLED_LOGIC_OP | vkCreateGraphicsPipelines | TODO | Create test |
-| Valid Logic Operations  | If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value | INVALID_LOGIC_OP | vkCreateGraphicsPipelines | TODO | Create test |
+| Enabled Logic Operations  | If logic operations is not enabled, logicOpEnable must be VK_FALSE | DISABLED_LOGIC_OP | vkCreateGraphicsPipelines | ColorBlendLogicOpTests | NA |
+| Valid Logic Operations  | If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value | INVALID_LOGIC_OP | vkCreateGraphicsPipelines | ColorBlendLogicOpTests | NA |
 | QueueFamilyIndex is Valid | Validates that QueueFamilyIndices are less an the number of QueueFamilies | INVALID_QUEUE_INDEX | vkCmdWaitEvents vkCmdPipelineBarrier vkCreateBuffer vkCreateImage | TODO | Create test |
-| Push Constants | Validate that the size of push constant ranges and updates does not exceed maxPushConstantSize | PUSH_CONSTANTS_ERROR | vkCreatePipelineLayout vkCmdPushConstants | TODO | Create test |
+| Invalid Queue Family Consistency | Validates that items created in one Queue Family are not submitted using a different one | INVALID_QUEUE_FAMILY | vkCmdExecuteCommands vkQueueSubmit | MismatchedQueueFamiliesOnSubmit |
+| Push Constants | Validate that the size of push constant ranges and updates does not exceed maxPushConstantSize | PUSH_CONSTANTS_ERROR | vkCreatePipelineLayout vkCmdPushConstants | InvalidPushConstants | NA |
+| Attachment Image Usage | Validate that Image attachment location does not conflict with the image's USAGE flags | INVALID_IMAGE_USAGE | vkCreateFramebuffer | FramebufferCreateErrors | NA |
+| Attachment Image Index | Validate that Image attachment references are appropriate and not out-of-bounds | INVALID_ATTACHMENT_INDEX | vkCreateRenderPass vkCreateFramebuffer | UnusedPreserveAttachment | NA |
 | NA | Enum used for informational messages | NONE | | TODO | None |
 | NA | Enum used for errors in the layer itself. This does not indicate an app issue, but instead a bug in the layer. | INTERNAL_ERROR | | TODO | None |
 | NA | Enum used when VK_LAYER_LUNARG_core_validation attempts to allocate memory for its own internal use and is unable to. | OUT_OF_MEMORY | | TODO | None |
-| NA | Enum used when VK_LAYER_LUNARG_core_validation attempts to allocate memory for its own internal use and is unable to. | OUT_OF_MEMORY | | TODO | None |
 
 ### VK_LAYER_LUNARG_core_validation Draw State Pending Work
 
@@ -138,7 +140,7 @@
 | NA | Enum used for informational messages | NONE | | TODO | None |
 
 ### VK_LAYER_LUNARG_core_validation Shader Checker Pending Work
- 
+
 See the Khronos github repository for Vulkan-LoaderAndValidationLayers for additional pending issues, or to submit new validation requests
 
 ### VK_LAYER_LUNARG_core_validation Memory Tracker Details Table
@@ -147,7 +149,7 @@
 | Check | Overview | ENUM MEMTRACK_* | Relevant API | Testname | Notes/TODO |
 | ----- | -------- | ---------------- | ------------ | -------- | ---------- |
 | Valid Command Buffer | Verifies that the command buffer was properly created and is currently valid | INVALID_CB | vkCmdBindPipeline vkCmdSetViewport vkCmdSetLineWidth vkCmdSetDepthBias vkCmdSetBlendConstants vkCmdSetDepthBounds vkCmdSetStencilCompareMask vkCmdSetStencilWriteMask vkCmdSetStencilReference vkBeginCommandBuffer vkResetCommandBuffer vkDestroyDevice vkFreeMemory | TODO | NA |
-| Valid Memory Object | Verifies that the memory object was properly created and is currently valid | INVALID_MEM_OBJ | vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkFreeMemory vkBindBufferMemory vkBindImageMemory vkQueueBindSparse | TODO | NA |
+| Valid Memory Object | Verifies that the memory object was properly created and is currently valid | INVALID_MEM_OBJ | vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkFreeMemory vkBindBufferMemory vkBindImageMemory vkQueueBindSparse | VertexBufferInvalid | NA |
 | Memory Aliasing | Flag error if image and/or buffer memory binding ranges overlap | INVALID_ALIASING | vkBindBufferMemory vkBindImageMemory | InvalidMemoryAliasing | Implement test |
 | Free Referenced Memory | Checks to see if memory being freed still has current references | FREED_MEM_REF | vmFreeMemory | TODO | NA |
 | Valid Object | Verifies that the specified Vulkan object was created properly and is currently valid | INVALID_OBJECT | vkCmdBindPipeline vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdUpdateBuffer vkCmdFillBuffer vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage | TODO | NA |
@@ -158,6 +160,8 @@
 | Immutable Memory Binding | Validates that non-sparse memory bindings are immutable, so objects are not re-boundt | REBIND_OBJECT | vkBindBufferMemory, vkBindImageMemory | RebindMemory | NA |
 | Image/Buffer Usage bits | Verify correct USAGE bits set based on how Images and Buffers are used | INVALID_USAGE_FLAG | vkCreateImage, vkCreateBuffer, vkCreateBufferView, vkCmdCopyBuffer, vkCmdCopyQueryPoolResults, vkCmdCopyImage, vkCmdBlitImage, vkCmdCopyBufferToImage, vkCmdCopyImageToBuffer, vkCmdUpdateBuffer, vkCmdFillBuffer  | InvalidUsageBits | NA |
 | Memory Map Range Checks | Validates that Memory Mapping Requests are valid for the Memory Object (in-range, not currently mapped on Map, currently mapped on UnMap, size is non-zero) | INVALID_MAP | vkMapMemory | InvalidMemoryMapping | NA |
+| Memory Type Index Checks | Validates that specified memory type indices are valid | INVALID_MEM_TYPE | vkBindImageMemory vkBindBufferMemory | TODO | Need to fix up and re-enable BindImageInvalidMemoryType test as noted in comment in test |
+| Memory Bound To Object Checks | Validates that memory was bound to image or buffer before use | OBJECT_NOT_BOUND | vkCreateImageView vkCreateBufferView vkCmdCopyImage vkCmdBlitImage vkCmdCopyBufferToImage vkCmdCopyImageToBuffer vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdResolveImage vkCmdUpdateBuffer vkCmdFillBuffer vkCmdBindIndexBuffer vkCmdBindVertexBuffers vkCmdDrawIndirect vkCmdDrawIndexedIndirect vkCmdDispatchIndirect vkCmdCopyBuffer vkCmdCopyQueryPoolResults| CreateBufferViewNoMemoryBoundToBuffer CreateImageViewNoMemoryBoundToImage ImageMemoryNotBound BufferMemoryNotBound | None |
 | NA | Enum used for informational messages | NONE | | TODO | None |
 | NA | Enum used for errors in the layer itself. This does not indicate an app issue, but instead a bug in the layer. | INTERNAL_ERROR | | TODO | None |
 
@@ -165,6 +169,21 @@
 
 See the Khronos github repository for Vulkan-LoaderAndValidationLayers for additional pending issues, or to submit new validation requests
 
+### VK_LAYER_LUNARG_core_validation Memory Device Limits Details Table
+Each device specifies a set of Device Limits with which the appropriate parameters should comply.  The core_validation layer contains device-limits related checks for which some amount of saved state information is necessary to complete the check.
+
+| Check | Overview | ENUM DEVLIMITS_* | Relevant API | Testname | Notes/TODO |
+| ----- | -------- | ---------------- | ---------------- | -------- | ---------- |
+| Valid instance | If an invalid instance is used, this error will be flagged | INVALID_INSTANCE | vkEnumeratePhysicalDevices | TODO | VK_LAYER_LUNARG_object_tracker should also catch this so if we made sure VK_LAYER_LUNARG_object_tracker was always on top, we could avoid this check |
+| Valid physical device | Enum used for informational messages | INVALID_PHYSICAL_DEVICE | vkEnumeratePhysicalDevices | TODO | VK_LAYER_LUNARG_object_tracker should also catch this so if we made sure VK_LAYER_LUNARG_object_tracker was always on top, we could avoid this check |
+| Query count checked | Signifies that a query call such as vkEnumeratePhysicalDevices or vkGetPhysicalDeviceQueueFamilyProperties has been called without querying the count | MISSING_QUERY_COUNT | vkEnumeratePhysicalDevices vkGetPhysicalDeviceQueueFamilyProperties | TODO | None |
+| Querying array counts | For API calls where an array count should be queried with an initial call and a NULL array pointer, verify that such a call was made before making a call with non-null array pointer. | MUST_QUERY_COUNT | vkEnumeratePhysicalDevices vkGetPhysicalDeviceQueueFamilyProperties | TODO | Create focused test |
+| Array count value | For API calls where an array of details is queried, verify that the size of the requested array matches the size of the array supported by the device. | COUNT_MISMATCH | vkEnumeratePhysicalDevices vkGetPhysicalDeviceQueueFamilyProperties | TODO | Create focused test |
+| Feature Request | Attempting to vkCreateDevice with a feature that is not supported by the underlying physical device | INVALID_FEATURE_REQUESTED | vkCreateDevice | TODO | Add validation test |
+| Queue Creation | When creating/requesting queues, make sure that QueueFamilyPropertiesIndex and index/count within that queue family are valid. | INVALID_QUEUE_CREATE_REQUEST | vkGetDeviceQueue vkCreateDevice | TODO | Create focused test |
+| NA | Enum used for informational messages | NONE | | TODO | None |
+
+
 ## VK_LAYER_LUNARG_parameter_validation
 
 ### VK_LAYER_LUNARG_parameter_validation Overview
@@ -175,12 +194,14 @@
 
 | Check | Overview | ENUM * | Relevant API | Testname | Notes/TODO |
 | ----- | -------- | ---------------- | ------------ | -------- | ---------- |
-| Valid Usage | Verifies that the value of a parameter is consistent with the valid usage criteria defined in the Vulkan specification | INVALID_USAGE | | TODO | NA |
+| Valid Usage | Verifies that the value of a parameter is consistent with the valid usage criteria defined in the Vulkan specification | INVALID_USAGE | vkCmdUpdateBuffer vkCmdFillBuffer | FillBufferAlignment UpdateBufferAlignment | NA |
 | Valid VkStructureType Value | Verifies that the sType field of a Vulkan structure contains the value expected for a structure of that type | INVALID_STRUCT_STYPE | | InvalidStructSType | NA |
 | Valid Structure pNext Value | Verifies that the pNext field of a Vulkan structure references a value that is compatible with a structure of that type or is NULL when a structure of that type has no compatible pNext values | INVALID_STRUCT_PNEXT | | InvalidStructPNext | NA |
 | Required Parameter | Verifies that a required parameter was not specified as 0 or NULL | REQUIRED_PARAMETER | | RequiredParameter | NA |
 | Reserved Parameter | Verifies that a parameter reserved for future use was specified as 0 or NULL | RESERVED_PARAMETER | | ReservedParameter | NA |
 | Unrecognized Value | Verifies that a Vulkan enumeration, VkFlags, or VkBool32 parameter contains a value that is recognized as valid for that type | UNRECOGNIZED_VALUE | | UnrecognizedValue | NA |
+| Device Limit Violation | Verifies that a parameter is within the limits advertised by the gpu | DEVICE_LIMIT | vkUpdateDescriptorSets vkCreateRenderPass | TODO | NA |
+| Device Feature Violation | Verifies that a requested feature is supported by the gpu | DEVICE_FEATURE | vkBeginCommandBuffer | TODO | NA |
 | Failed Call Return Code | Provides a description of a failure code returned by a Vulkan API call | FAILURE_RETURN_CODE | | FailedReturnValue | NA |
 | NA | Enum used for informational messages | NONE | | TODO | None |
 
@@ -201,7 +222,7 @@
 | Check | Overview | ENUM IMAGE_* | Relevant API | Testname | Notes/TODO |
 | ----- | -------- | ---------------- | ------------ | -------- | ---------- |
 | Image Format | Verifies that requested format is a supported Vulkan format on this device | FORMAT_UNSUPPORTED | vkCreateImage vkCreateRenderPass | ImageLayerUnsupportedFormat | NA |
-| RenderPass Attachments | Validates that attachment image layouts, loadOps, and storeOps are valid Vulkan values | RENDERPASS_INVALID_ATTACHMENT | vkCreateRenderPass | TODO | NA |
+| RenderPass Attachments | Validates that attachment image format, layouts, loadOps, and storeOps are valid Vulkan values | RENDERPASS_INVALID_ATTACHMENT | vkCreateRenderPass | AttachmentDescriptionUndefinedFormat | Tests are needed for loadops, storeops, layouts, and bad depth format |
 | Subpass DS Settings | Verifies that if there is no depth attachment then the subpass attachment is set to VK_ATTACHMENT_UNUSED | RENDERPASS_INVALID_DS_ATTACHMENT | vkCreateRenderPass | TODO | NA |
 | View Creation | Verify that requested Image View Creation parameters are reasonable for the image that the view is being created for | VIEW_CREATE_ERROR | vkCreateImageView | ImageLayerViewTests | NA |
 | Image Aspects | Verify that Image commands are using valid Image Aspect flags | INVALID_IMAGE_ASPECT | vkCreateImageView vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdClearAttachments vkCmdCopyImage vkCmdCopyImageToBuffer vkCmdCopyBufferToImage vkCmdResolveImage vkCmdBlitImage | InvalidImageViewAspect | NA |
@@ -215,6 +236,7 @@
 | Verify Image Format Limits | Verifies that image creation parameters are with the device format limits | INVALID_FORMAT_LIMITS_VIOLATION | vkCreateImage | ImageFormatLimits | NA |
 | Verify Layout | Verifies the layouts are valid for this image operation | INVALID_LAYOUT | vkCreateImage vkCmdClearColorImage | TODO | ImageFormatLimits |
 | Verify Image Extents | Validates that image extent limits are not invalid | INVALID_EXTENTS | vkCmdCopyImage | CopyImageLayerCountMismatch | NA |
+| Verify Usage | Verifies the image was created with usage valid for this image operation | INVALID_USAGE | vkCmdClearColorImage | TODO | ClearImageErrors |
 | NA | Enum used for informational messages | NONE | | TODO | None |
 
 ### VK_LAYER_LUNARG_image Pending Work
@@ -280,40 +302,6 @@
 
 See the Khronos github repository for Vulkan-LoaderAndValidationLayers for additional pending issues, or to submit new validation requests
 
-## VK_LAYER_LUNARG_device_limits
-
-### VK_LAYER_LUNARG_device_limits Overview
-
-This layer is a work in progress. VK_LAYER_LUNARG_device_limits layer is intended to capture two broad categories of errors:
- 1. Incorrect use of APIs to query device capabilities
- 2. Attempt to use API functionality beyond the capability of the underlying device
-
-For the first category, the layer tracks which calls are made and flags errors if calls are excluded that should not be, or if call sequencing is incorrect. An example is an app that assumes attempts to Query and use queues without ever having called vkGetPhysicalDeviceQueueFamilyProperties(). Also, if an app is calling vkGetPhysicalDeviceQueueFamilyProperties() to retrieve properties with some assumed count for array size instead of first calling vkGetPhysicalDeviceQueueFamilyProperties() w/ a NULL pQueueFamilyProperties parameter in order to query the actual count.
-For the second category of errors, VK_LAYER_LUNARG_device_limits stores its own internal record of underlying device capabilities and flags errors if requests are made beyond those limits. Most (all?) of the limits are queried via vkGetPhysicalDevice* calls.
-
-### VK_LAYER_LUNARG_device_limits Details Table
-
-| Check | Overview | ENUM DEVLIMITS_* | Relevant API | Testname | Notes/TODO |
-| ----- | -------- | ---------------- | ---------------- | -------- | ---------- |
-| Valid instance | If an invalid instance is used, this error will be flagged | INVALID_INSTANCE | vkEnumeratePhysicalDevices | TODO | VK_LAYER_LUNARG_object_tracker should also catch this so if we made sure VK_LAYER_LUNARG_object_tracker was always on top, we could avoid this check |
-| Valid physical device | Enum used for informational messages | INVALID_PHYSICAL_DEVICE | vkEnumeratePhysicalDevices | TODO | VK_LAYER_LUNARG_object_tracker should also catch this so if we made sure VK_LAYER_LUNARG_object_tracker was always on top, we could avoid this check |
-| Valid inherited query | If an invalid inherited query is used, this error will be flagged | INVALID_INHERITED_QUERY | vkBeginCommandBuffer | TODO | None |
-| Valid attachment count | If the number of attachments exceeds the device max, this error will be flagged | INVALID_ATTACHMENT_COUNT | vkCreateRenderPass | TODO | None |
-| Querying array counts | For API calls where an array count should be queried with an initial call and a NULL array pointer, verify that such a call was made before making a call with non-null array pointer. | MUST_QUERY_COUNT | vkEnumeratePhysicalDevices vkGetPhysicalDeviceQueueFamilyProperties | TODO | Create focused test |
-| Array count value | For API calls where an array of details is queried, verify that the size of the requested array matches the size of the array supported by the device. | COUNT_MISMATCH | vkEnumeratePhysicalDevices vkGetPhysicalDeviceQueueFamilyProperties | TODO | Create focused test |
-| Queue Creation | When creating/requesting queues, make sure that QueueFamilyPropertiesIndex and index/count within that queue family are valid. | INVALID_QUEUE_CREATE_REQUEST | vkGetDeviceQueue vkCreateDevice | TODO | Create focused test |
-| API Call Sequencing | This is a general error indicating that an app did not use vkGetPhysicalDevice* and other such query calls, but rather made an assumption about device capabilities. | INVALID_CALL_SEQUENCE | vkCreateDevice | TODO | Add validation test |
-| Feature Request | Attempting to vkCreateDevice with a feature that is not supported by the underlying physical device. | INVALID_FEATURE_REQUESTED | vkCreateDevice | TODO | Add validation test |
-| Alignment | When updating a buffer, data should be aligned on 4 byte boundaries  | INVALID_BUFFER_UPDATE_ALIGNMENT | vkCmdUpdateBuffer | UpdateBufferAlignment | NA |
-| Alignment | When filling a buffer, data should be aligned on 4 byte boundaries  | INVALID_BUFFER_UPDATE_ALIGNMENT | vkCmdFillBuffer | UpdateBufferAlignment | NA |
-| Storage Buffer Alignment  | Storage Buffer offsets must agree with offset alignment device limit | INVALID_STORAGE_BUFFER_OFFSET | vkBindBufferMemory vkUpdateDescriptorSets | TODO | Create test |
-| Uniform Buffer Alignment  | Uniform Buffer offsets must agree with offset alignment device limit | INVALID_UNIFORM_BUFFER_OFFSET | vkBindBufferMemory vkUpdateDescriptorSets | TODO | Create test |
-| NA | Enum used for informational messages | NONE | | TODO | None |
-
-### VK_LAYER_LUNARG_device_limits Pending Work
-
-See the Khronos github repository for Vulkan-LoaderAndValidationLayers for additional pending issues, or to submit new validation requests
-
 ## VK_LAYER_LUNARG_swapchain
 
 ### Swapchain Overview
@@ -335,7 +323,7 @@
 | vkCreateSwapchainKHR(pCreateInfo->imageExtent) | Validates vkCreateSwapchainKHR(pCreateInfo->imageExtent) when window has a fixed size | CREATE_SWAP_EXTENTS_NO_MATCH_WIN | vkCreateSwapchainKHR | TODO | None |
 | vkCreateSwapchainKHR(pCreateInfo->preTransform) | Validates vkCreateSwapchainKHR(pCreateInfo->preTransform) | CREATE_SWAP_BAD_PRE_TRANSFORM | vkCreateSwapchainKHR | TODO | None |
 | vkCreateSwapchainKHR(pCreateInfo->compositeAlpha) | Validates vkCreateSwapchainKHR(pCreateInfo->compositeAlpha) | CREATE_SWAP_BAD_COMPOSITE_ALPHA | vkCreateSwapchainKHR | TODO | None |
-| vkCreateSwapchainKHR(pCreateInfo->imageArraySize) | Validates vkCreateSwapchainKHR(pCreateInfo->imageArraySize) | CREATE_SWAP_BAD_IMG_ARRAY_SIZE | vkCreateSwapchainKHR | TODO | None |
+| vkCreateSwapchainKHR(pCreateInfo->imageArrayLayers) | Validates vkCreateSwapchainKHR(pCreateInfo->imageArrayLayers) | CREATE_SWAP_BAD_IMG_ARRAY_LAYERS | vkCreateSwapchainKHR | TODO | None |
 | vkCreateSwapchainKHR(pCreateInfo->imageUsageFlags) | Validates vkCreateSwapchainKHR(pCreateInfo->imageUsageFlags) | CREATE_SWAP_BAD_IMG_USAGE_FLAGS | vkCreateSwapchainKHR | TODO | None |
 | vkCreateSwapchainKHR(pCreateInfo->imageColorSpace) | Validates vkCreateSwapchainKHR(pCreateInfo->imageColorSpace) | CREATE_SWAP_BAD_IMG_COLOR_SPACE | vkCreateSwapchainKHR | TODO | None |
 | vkCreateSwapchainKHR(pCreateInfo->imageFormat) | Validates vkCreateSwapchainKHR(pCreateInfo->imageFormat) | CREATE_SWAP_BAD_IMG_FORMAT | vkCreateSwapchainKHR | TODO | None |
@@ -359,6 +347,10 @@
 | Valid queueFamilyIndex value | Validates that a queueFamilyIndex value is less-than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties | QUEUE_FAMILY_INDEX_TOO_LARGE | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | None |
 | Supported combination of queue and surface | Validates that the surface associated with a swapchain was seen to support the queueFamilyIndex of a given queue | SURFACE_NOT_SUPPORTED_WITH_QUEUE | vkQueuePresentKHR | TODO | None |
 | Proper synchronization of acquired images | vkAcquireNextImageKHR should be called with a valid semaphore and/or fence | NO_SYNC_FOR_ACQUIRE | vkAcquireNextImageKHR | TODO | None |
+| Potential use before query | Validates that Display Plane Properties are queried before getting supported Display Planes | GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | actually: vkGetDisplayPlaneSupportedDisplaysKHR |
+| Index too large | Validates index is in range of phys device display plane props | PLANE_INDEX_TOO_LARGE | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | actually: vkGetDisplayPlaneSupportedDisplaysKHR |
+| Index too large | Validates index is in range of phys device display plane props | PLANE_INDEX_TOO_LARGE | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | actually: vkGetDisplayPlaneCapabilitiesKHR |
+
 
 Note: The following platform-specific functions are not mentioned above, because they are protected by ifdefs, which cause test failures:
 
diff --git a/layers/windows/VkLayer_core_validation.json b/layers/windows/VkLayer_core_validation.json
index e58dc0a..a8d8cef 100644
--- a/layers/windows/VkLayer_core_validation.json
+++ b/layers/windows/VkLayer_core_validation.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_core_validation",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_core_validation.dll",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/windows/VkLayer_device_limits.json b/layers/windows/VkLayer_device_limits.json
deleted file mode 100644
index 18e5212..0000000
--- a/layers/windows/VkLayer_device_limits.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "file_format_version" : "1.0.0",
-    "layer" : {
-        "name": "VK_LAYER_LUNARG_device_limits",
-        "type": "GLOBAL",
-        "library_path": ".\\VkLayer_device_limits.dll",
-        "api_version": "1.0.13",
-        "implementation_version": "1",
-        "description": "LunarG Validation Layer",
-        "instance_extensions": [
-             {
-                 "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
-             }
-         ]
-    }
-}
diff --git a/layers/windows/VkLayer_image.json b/layers/windows/VkLayer_image.json
index a898317..a27dd5c 100644
--- a/layers/windows/VkLayer_image.json
+++ b/layers/windows/VkLayer_image.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_image",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_image.dll",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/windows/VkLayer_object_tracker.json b/layers/windows/VkLayer_object_tracker.json
index afe36bb..1b97c67 100644
--- a/layers/windows/VkLayer_object_tracker.json
+++ b/layers/windows/VkLayer_object_tracker.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_object_tracker",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_object_tracker.dll",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/windows/VkLayer_parameter_validation.json b/layers/windows/VkLayer_parameter_validation.json
index b946ba2..efe91db 100644
--- a/layers/windows/VkLayer_parameter_validation.json
+++ b/layers/windows/VkLayer_parameter_validation.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_parameter_validation",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_parameter_validation.dll",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/windows/VkLayer_swapchain.json b/layers/windows/VkLayer_swapchain.json
index 415146a..b06c95c 100644
--- a/layers/windows/VkLayer_swapchain.json
+++ b/layers/windows/VkLayer_swapchain.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_LUNARG_swapchain",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_swapchain.dll",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/windows/VkLayer_threading.json b/layers/windows/VkLayer_threading.json
index 206a246..dabee1f 100644
--- a/layers/windows/VkLayer_threading.json
+++ b/layers/windows/VkLayer_threading.json
@@ -4,13 +4,13 @@
         "name": "VK_LAYER_GOOGLE_threading",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_threading.dll",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "Google Validation Layer",
         "instance_extensions": [
              {
                  "name": "VK_EXT_debug_report",
-                 "spec_version": "2"
+                 "spec_version": "3"
              }
          ]
     }
diff --git a/layers/windows/VkLayer_unique_objects.json b/layers/windows/VkLayer_unique_objects.json
index 3e0c47a..40a7c63 100644
--- a/layers/windows/VkLayer_unique_objects.json
+++ b/layers/windows/VkLayer_unique_objects.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_unique_objects",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_unique_objects.dll",
-        "api_version": "1.0.13",
+        "api_version": "1.0.21",
         "implementation_version": "1",
         "description": "Google Validation Layer"
     }
diff --git a/libs/vkjson/.clang-format b/libs/vkjson/.clang-format
new file mode 100644
index 0000000..3f19e61
--- /dev/null
+++ b/libs/vkjson/.clang-format
@@ -0,0 +1 @@
+BasedOnStyle: Chromium
diff --git a/libs/vkjson/CMakeLists.txt b/libs/vkjson/CMakeLists.txt
index b650609..fc69bb6 100644
--- a/libs/vkjson/CMakeLists.txt
+++ b/libs/vkjson/CMakeLists.txt
@@ -28,7 +28,7 @@
 	${CMAKE_CURRENT_SOURCE_DIR}/../../include/vulkan
 	)
 
-add_library(vkjson STATIC vkjson.cc vkjson_device.cc ../../loader/cJSON.c)
+add_library(vkjson STATIC vkjson.cc vkjson_instance.cc ../../loader/cJSON.c)
 
 if(UNIX)
     add_executable(vkjson_unittest vkjson_unittest.cc)
diff --git a/libs/vkjson/vkjson.cc b/libs/vkjson/vkjson.cc
index f86d3e3..aa3719d 100644
--- a/libs/vkjson/vkjson.cc
+++ b/libs/vkjson/vkjson.cc
@@ -327,17 +327,28 @@
 }
 
 template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkJsonAllProperties* properties) {
-  return
-    visitor->Visit("properties", &properties->properties) &&
-    visitor->Visit("features", &properties->features) &&
-    visitor->Visit("memory", &properties->memory) &&
-    visitor->Visit("queues", &properties->queues) &&
-    visitor->Visit("extensions", &properties->extensions) &&
-    visitor->Visit("layers", &properties->layers) &&
-    visitor->Visit("formats", &properties->formats);
+inline bool Iterate(Visitor* visitor, VkJsonLayer* layer) {
+  return visitor->Visit("properties", &layer->properties) &&
+         visitor->Visit("extensions", &layer->extensions);
 }
 
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonDevice* device) {
+  return visitor->Visit("properties", &device->properties) &&
+         visitor->Visit("features", &device->features) &&
+         visitor->Visit("memory", &device->memory) &&
+         visitor->Visit("queues", &device->queues) &&
+         visitor->Visit("extensions", &device->extensions) &&
+         visitor->Visit("layers", &device->layers) &&
+         visitor->Visit("formats", &device->formats);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonInstance* instance) {
+  return visitor->Visit("layers", &instance->layers) &&
+         visitor->Visit("extensions", &instance->extensions) &&
+         visitor->Visit("devices", &instance->devices);
+}
 
 template <typename T>
 using EnableForArithmetic =
@@ -663,15 +674,24 @@
 
 }  // anonymous namespace
 
-std::string VkJsonAllPropertiesToJson(
-    const VkJsonAllProperties& properties) {
-  return VkTypeToJson(properties);
+std::string VkJsonInstanceToJson(const VkJsonInstance& instance) {
+  return VkTypeToJson(instance);
 }
 
-bool VkJsonAllPropertiesFromJson(
-    const std::string& json, VkJsonAllProperties* properties,
-    std::string* errors) {
-  return VkTypeFromJson(json, properties, errors);
+bool VkJsonInstanceFromJson(const std::string& json,
+                            VkJsonInstance* instance,
+                            std::string* errors) {
+  return VkTypeFromJson(json, instance, errors);
+}
+
+std::string VkJsonDeviceToJson(const VkJsonDevice& device) {
+  return VkTypeToJson(device);
+}
+
+bool VkJsonDeviceFromJson(const std::string& json,
+                          VkJsonDevice* device,
+                          std::string* errors) {
+  return VkTypeFromJson(json, device, errors);
 };
 
 std::string VkJsonImageFormatPropertiesToJson(
diff --git a/libs/vkjson/vkjson.h b/libs/vkjson/vkjson.h
index e60135b..b703750 100644
--- a/libs/vkjson/vkjson.h
+++ b/libs/vkjson/vkjson.h
@@ -33,8 +33,13 @@
 #undef max
 #endif
 
-struct VkJsonAllProperties {
-  VkJsonAllProperties() {
+struct VkJsonLayer {
+  VkLayerProperties properties;
+  std::vector<VkExtensionProperties> extensions;
+};
+
+struct VkJsonDevice {
+  VkJsonDevice() {
           memset(&properties, 0, sizeof(VkPhysicalDeviceProperties));
           memset(&features, 0, sizeof(VkPhysicalDeviceFeatures));
           memset(&memory, 0, sizeof(VkPhysicalDeviceMemoryProperties));
@@ -48,13 +53,23 @@
   std::map<VkFormat, VkFormatProperties> formats;
 };
 
-VkJsonAllProperties VkJsonGetAllProperties(VkPhysicalDevice physicalDevice);
+struct VkJsonInstance {
+  std::vector<VkJsonLayer> layers;
+  std::vector<VkExtensionProperties> extensions;
+  std::vector<VkJsonDevice> devices;
+};
 
-std::string VkJsonAllPropertiesToJson(
-    const VkJsonAllProperties& properties);
-bool VkJsonAllPropertiesFromJson(
-    const std::string& json, VkJsonAllProperties* properties,
-    std::string* errors);
+VkJsonInstance VkJsonGetInstance();
+std::string VkJsonInstanceToJson(const VkJsonInstance& instance);
+bool VkJsonInstanceFromJson(const std::string& json,
+                            VkJsonInstance* instance,
+                            std::string* errors);
+
+VkJsonDevice VkJsonGetDevice(VkPhysicalDevice device);
+std::string VkJsonDeviceToJson(const VkJsonDevice& device);
+bool VkJsonDeviceFromJson(const std::string& json,
+                          VkJsonDevice* device,
+                          std::string* errors);
 
 std::string VkJsonImageFormatPropertiesToJson(
     const VkImageFormatProperties& properties);
@@ -62,4 +77,20 @@
                                          VkImageFormatProperties* properties,
                                          std::string* errors);
 
+// Backward-compatibility aliases
+typedef VkJsonDevice VkJsonAllProperties;
+inline VkJsonAllProperties VkJsonGetAllProperties(
+    VkPhysicalDevice physicalDevice) {
+  return VkJsonGetDevice(physicalDevice);
+}
+inline std::string VkJsonAllPropertiesToJson(
+    const VkJsonAllProperties& properties) {
+  return VkJsonDeviceToJson(properties);
+}
+inline bool VkJsonAllPropertiesFromJson(const std::string& json,
+                                        VkJsonAllProperties* properties,
+                                        std::string* errors) {
+  return VkJsonDeviceFromJson(json, properties, errors);
+}
+
 #endif  // VKJSON_H_
diff --git a/libs/vkjson/vkjson_device.cc b/libs/vkjson/vkjson_device.cc
deleted file mode 100644
index 88f4d44..0000000
--- a/libs/vkjson/vkjson_device.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2015-2016 The Khronos Group Inc.
-// Copyright (c) 2015-2016 Valve Corporation
-// Copyright (c) 2015-2016 LunarG, Inc.
-// Copyright (c) 2015-2016 Google, Inc.
-//
-// Licensed under the Apache 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
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// 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.
-///////////////////////////////////////////////////////////////////////////////
-
-#define VK_PROTOTYPES
-#include "vkjson.h"
-
-#include <utility>
-
-VkJsonAllProperties VkJsonGetAllProperties(VkPhysicalDevice physical_device) {
-  VkJsonAllProperties properties;
-  vkGetPhysicalDeviceProperties(physical_device, &properties.properties);
-  vkGetPhysicalDeviceFeatures(physical_device, &properties.features);
-  vkGetPhysicalDeviceMemoryProperties(physical_device, &properties.memory);
-
-  uint32_t queue_family_count = 0;
-  vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count,
-                                           nullptr);
-  if (queue_family_count > 0) {
-    properties.queues.resize(queue_family_count);
-    vkGetPhysicalDeviceQueueFamilyProperties(
-        physical_device, &queue_family_count, properties.queues.data());
-  }
-
-  // Only device extensions.
-  // TODO(piman): do we want to show layer extensions?
-  uint32_t extension_count = 0;
-  vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
-                                       &extension_count, nullptr);
-  if (extension_count > 0) {
-    properties.extensions.resize(extension_count);
-    vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
-                                         &extension_count,
-                                         properties.extensions.data());
-  }
-
-  uint32_t layer_count = 0;
-  vkEnumerateDeviceLayerProperties(physical_device, &layer_count, nullptr);
-  if (layer_count > 0) {
-    properties.layers.resize(layer_count);
-    vkEnumerateDeviceLayerProperties(physical_device, &layer_count,
-                                     properties.layers.data());
-  }
-
-  VkFormatProperties format_properties = {};
-  for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8;
-       format <= VK_FORMAT_END_RANGE;
-       format = static_cast<VkFormat>(format + 1)) {
-    vkGetPhysicalDeviceFormatProperties(physical_device, format,
-                                        &format_properties);
-    if (format_properties.linearTilingFeatures ||
-        format_properties.optimalTilingFeatures ||
-        format_properties.bufferFeatures) {
-      properties.formats.insert(std::make_pair(format, format_properties));
-    }
-  }
-  return properties;
-}
diff --git a/libs/vkjson/vkjson_info.cc b/libs/vkjson/vkjson_info.cc
index b5b0c3e..dc80822 100644
--- a/libs/vkjson/vkjson_info.cc
+++ b/libs/vkjson/vkjson_info.cc
@@ -21,6 +21,7 @@
 #define VK_PROTOTYPES
 #include "vkjson.h"
 
+#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -30,6 +31,7 @@
 const uint32_t unsignedNegOne = (uint32_t)(-1);
 
 struct Options {
+  bool instance = false;
   uint32_t device_index = unsignedNegOne;
   std::string device_name;
   std::string output_file;
@@ -38,7 +40,9 @@
 bool ParseOptions(int argc, char* argv[], Options* options) {
   for (int i = 1; i < argc; ++i) {
     std::string arg(argv[i]);
-    if (arg == "--first" || arg == "-f") {
+    if (arg == "--instance" || arg == "-i") {
+      options->instance = true;
+    } else if (arg == "--first" || arg == "-f") {
       options->device_index = 0;
     } else {
       ++i;
@@ -64,26 +68,64 @@
       }
     }
   }
+  if (options->instance && (options->device_index != unsignedNegOne ||
+                            !options->device_name.empty())) {
+    std::cerr << "Specifying a specific device is incompatible with dumping "
+                 "the whole instance." << std::endl;
+    return false;
+  }
   if (options->device_index != unsignedNegOne && !options->device_name.empty()) {
     std::cerr << "Must specify only one of device index and device name."
               << std::endl;
     return false;
   }
-  if (!options->output_file.empty() && options->device_index == unsignedNegOne &&
-      options->device_name.empty()) {
-    std::cerr << "Must specify device index or device name when specifying "
-                 "output file"
+  if (options->instance && options->output_file.empty()) {
+    std::cerr << "Must specify an output file when dumping the whole instance."
               << std::endl;
     return false;
   }
+  if (!options->output_file.empty() && !options->instance &&
+      options->device_index == unsignedNegOne && options->device_name.empty()) {
+    std::cerr << "Must specify instance, device index, or device name when "
+                 "specifying "
+                 "output file." << std::endl;
+    return false;
+  }
   return true;
 }
 
-bool DumpProperties(const VkJsonAllProperties& props, const Options& options) {
-  std::string device_name(props.properties.deviceName);
-  std::string output_file = options.output_file;
-  if (output_file.empty())
-    output_file = device_name + ".json";
+bool Dump(const VkJsonInstance& instance, const Options& options) {
+  const VkJsonDevice* out_device = nullptr;
+  if (options.device_index != unsignedNegOne) {
+    if (static_cast<uint32_t>(options.device_index) >=
+        instance.devices.size()) {
+      std::cerr << "Error: device " << options.device_index
+                << " requested but only " << instance.devices.size()
+                << " devices found." << std::endl;
+      return false;
+    }
+    out_device = &instance.devices[options.device_index];
+  } else if (!options.device_name.empty()) {
+    for (const auto& device : instance.devices) {
+      if (device.properties.deviceName == options.device_name) {
+        out_device = &device;
+      }
+    }
+    if (!out_device) {
+      std::cerr << "Error: device '" << options.device_name
+                << "' requested but not found." << std::endl;
+      return false;
+    }
+  }
+
+  std::string output_file;
+  if (options.output_file.empty()) {
+    assert(out_device);
+    output_file.assign(out_device->properties.deviceName);
+    output_file.append(".json");
+  } else {
+    output_file = options.output_file;
+  }
   FILE* file = nullptr;
   if (output_file == "-") {
     file = stdout;
@@ -95,13 +137,17 @@
     }
   }
 
-  std::string json = VkJsonAllPropertiesToJson(props) + '\n';
+  std::string json = out_device ? VkJsonDeviceToJson(*out_device)
+                                : VkJsonInstanceToJson(instance);
   fwrite(json.data(), 1, json.size(), file);
+  fputc('\n', file);
 
   if (output_file != "-") {
     fclose(file);
-    std::cout << "Wrote file " << output_file << " for device " << device_name
-              << "." << std::endl;
+    std::cout << "Wrote file " << output_file;
+    if (out_device)
+      std::cout << " for device " << out_device->properties.deviceName;
+    std::cout << "." << std::endl;
   }
   return true;
 }
@@ -111,79 +157,16 @@
   if (!ParseOptions(argc, argv, &options))
     return 1;
 
-  const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
-                                      nullptr,
-                                      "vkjson_info",
-                                      1,
-                                      "",
-                                      0,
-                                      VK_API_VERSION_1_0};
-  VkInstanceCreateInfo instance_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
-                                        nullptr,
-                                        0,
-                                        &app_info,
-                                        0,
-                                        nullptr,
-                                        0,
-                                        nullptr};
-  VkInstance instance;
-  VkResult result = vkCreateInstance(&instance_info, nullptr, &instance);
-  if (result != VK_SUCCESS) {
-    std::cerr << "Error: vkCreateInstance failed with error: " << result
-              << "." << std::endl;
-    return 1;
-  }
-
-  uint32_t device_count = 0;
-  result = vkEnumeratePhysicalDevices(instance, &device_count, nullptr);
-  if (result != VK_SUCCESS) {
-    std::cerr << "Error: vkEnumeratePhysicalDevices failed with error "
-              << result << "." << std::endl;
-    return 1;
-  }
-  if (device_count == 0) {
-    std::cerr << "Error: no Vulkan device found.";
-    return 1;
-  }
-
-  std::vector<VkPhysicalDevice> physical_devices(device_count,
-                                                 VkPhysicalDevice());
-  result = vkEnumeratePhysicalDevices(instance, &device_count,
-                                      physical_devices.data());
-  if (result != VK_SUCCESS) {
-    std::cerr << "Error: vkEnumeratePhysicalDevices failed with error "
-              << result << std::endl;
-    return 1;
-  }
-
-  if (options.device_index != unsignedNegOne) {
-    if (static_cast<uint32_t>(options.device_index) >= device_count) {
-      std::cerr << "Error: device " << options.device_index
-                << " requested but only " << device_count << " found."
-                << std::endl;
-      return 1;
+  VkJsonInstance instance = VkJsonGetInstance();
+  if (options.instance || options.device_index != unsignedNegOne ||
+      !options.device_name.empty()) {
+    Dump(instance, options);
+  } else {
+    for (uint32_t i = 0, n = static_cast<uint32_t>(instance.devices.size()); i < n; i++) {
+      options.device_index = i;
+      Dump(instance, options);
     }
-    auto props = VkJsonGetAllProperties(physical_devices[options.device_index]);
-    if (!DumpProperties(props, options))
-      return 1;
-    return 0;
   }
 
-  bool found = false;
-  for (auto physical_device : physical_devices) {
-    auto props = VkJsonGetAllProperties(physical_device);
-    if (!options.device_name.empty() &&
-        options.device_name != props.properties.deviceName)
-      continue;
-    if (!DumpProperties(props, options))
-      return 1;
-    found = true;
-  }
-
-  if (!found) {
-    std::cerr << "Error: device " << options.device_name << " not found."
-              << std::endl;
-    return 1;
-  }
   return 0;
 }
diff --git a/libs/vkjson/vkjson_instance.cc b/libs/vkjson/vkjson_instance.cc
new file mode 100644
index 0000000..eea945a
--- /dev/null
+++ b/libs/vkjson/vkjson_instance.cc
@@ -0,0 +1,164 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015-2016 The Khronos Group Inc.
+// Copyright (c) 2015-2016 Valve Corporation
+// Copyright (c) 2015-2016 LunarG, Inc.
+// Copyright (c) 2015-2016 Google, Inc.
+//
+// Licensed under the Apache 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
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// 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.
+///////////////////////////////////////////////////////////////////////////////
+
+#define VK_PROTOTYPES
+#include "vkjson.h"
+
+#include <utility>
+
+namespace {
+bool EnumerateExtensions(const char* layer_name,
+                         std::vector<VkExtensionProperties>* extensions) {
+  VkResult result;
+  uint32_t count = 0;
+  result = vkEnumerateInstanceExtensionProperties(layer_name, &count, nullptr);
+  if (result != VK_SUCCESS)
+    return false;
+  extensions->resize(count);
+  result = vkEnumerateInstanceExtensionProperties(layer_name, &count,
+                                                  extensions->data());
+  if (result != VK_SUCCESS)
+    return false;
+  return true;
+}
+
+}  // anonymous namespace
+
+VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
+  VkJsonDevice device;
+  vkGetPhysicalDeviceProperties(physical_device, &device.properties);
+  vkGetPhysicalDeviceFeatures(physical_device, &device.features);
+  vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory);
+
+  uint32_t queue_family_count = 0;
+  vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count,
+                                           nullptr);
+  if (queue_family_count > 0) {
+    device.queues.resize(queue_family_count);
+    vkGetPhysicalDeviceQueueFamilyProperties(
+        physical_device, &queue_family_count, device.queues.data());
+  }
+
+  // Only device extensions.
+  // TODO(piman): do we want to show layer extensions?
+  uint32_t extension_count = 0;
+  vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
+                                       &extension_count, nullptr);
+  if (extension_count > 0) {
+    device.extensions.resize(extension_count);
+    vkEnumerateDeviceExtensionProperties(
+        physical_device, nullptr, &extension_count, device.extensions.data());
+  }
+
+  uint32_t layer_count = 0;
+  vkEnumerateDeviceLayerProperties(physical_device, &layer_count, nullptr);
+  if (layer_count > 0) {
+    device.layers.resize(layer_count);
+    vkEnumerateDeviceLayerProperties(physical_device, &layer_count,
+                                     device.layers.data());
+  }
+
+  VkFormatProperties format_properties = {};
+  for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8;
+       format <= VK_FORMAT_END_RANGE;
+       format = static_cast<VkFormat>(format + 1)) {
+    vkGetPhysicalDeviceFormatProperties(physical_device, format,
+                                        &format_properties);
+    if (format_properties.linearTilingFeatures ||
+        format_properties.optimalTilingFeatures ||
+        format_properties.bufferFeatures) {
+      device.formats.insert(std::make_pair(format, format_properties));
+    }
+  }
+  return device;
+}
+
+VkJsonInstance VkJsonGetInstance() {
+  VkJsonInstance instance;
+  VkResult result;
+  uint32_t count;
+
+  count = 0;
+  result = vkEnumerateInstanceLayerProperties(&count, nullptr);
+  if (result != VK_SUCCESS)
+    return VkJsonInstance();
+  if (count > 0) {
+    std::vector<VkLayerProperties> layers(count);
+    result = vkEnumerateInstanceLayerProperties(&count, layers.data());
+    if (result != VK_SUCCESS)
+      return VkJsonInstance();
+    instance.layers.reserve(count);
+    for (auto& layer : layers) {
+      instance.layers.push_back(VkJsonLayer{layer, std::vector<VkExtensionProperties>()});
+      if (!EnumerateExtensions(layer.layerName,
+                               &instance.layers.back().extensions))
+        return VkJsonInstance();
+    }
+  }
+
+  if (!EnumerateExtensions(nullptr, &instance.extensions))
+    return VkJsonInstance();
+
+  std::vector<const char*> layer_names;
+  layer_names.reserve(instance.layers.size());
+  for (auto& layer : instance.layers)
+    layer_names.push_back(layer.properties.layerName);
+
+  const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
+                                      nullptr,
+                                      "vkjson_info",
+                                      1,
+                                      "",
+                                      0,
+                                      VK_API_VERSION_1_0};
+  VkInstanceCreateInfo instance_info = {
+      VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+      nullptr,
+      0,
+      &app_info,
+      static_cast<uint32_t>(layer_names.size()),
+      layer_names.data(),
+      0,
+      nullptr};
+  VkInstance vkinstance;
+  result = vkCreateInstance(&instance_info, nullptr, &vkinstance);
+  if (result != VK_SUCCESS)
+    return VkJsonInstance();
+
+  count = 0;
+  result = vkEnumeratePhysicalDevices(vkinstance, &count, nullptr);
+  if (result != VK_SUCCESS) {
+    vkDestroyInstance(vkinstance, nullptr);
+    return VkJsonInstance();
+  }
+  std::vector<VkPhysicalDevice> devices(count, VK_NULL_HANDLE);
+  result = vkEnumeratePhysicalDevices(vkinstance, &count, devices.data());
+  if (result != VK_SUCCESS) {
+    vkDestroyInstance(vkinstance, nullptr);
+    return VkJsonInstance();
+  }
+
+  instance.devices.reserve(devices.size());
+  for (auto device : devices)
+    instance.devices.emplace_back(VkJsonGetDevice(device));
+
+  vkDestroyInstance(vkinstance, nullptr);
+  return instance;
+}
diff --git a/libs/vkjson/vkjson_unittest.cc b/libs/vkjson/vkjson_unittest.cc
index 26ae6b7..5c6839a 100644
--- a/libs/vkjson/vkjson_unittest.cc
+++ b/libs/vkjson/vkjson_unittest.cc
@@ -45,37 +45,39 @@
   std::string errors;
   bool result = false;
 
+  VkJsonInstance instance;
+  instance.devices.resize(1);
+  VkJsonDevice& device = instance.devices[0];
+
   const char name[] = "Test device";
-  VkJsonAllProperties device_props;
-  memcpy(device_props.properties.deviceName, name, sizeof(name));
-  device_props.properties.limits.maxImageDimension1D = 3;
-  device_props.properties.limits.maxSamplerLodBias = 3.5f;
-  device_props.properties.limits.bufferImageGranularity = 0x1ffffffffull;
-  device_props.properties.limits.maxViewportDimensions[0] = 1;
-  device_props.properties.limits.maxViewportDimensions[1] = 2;
+  memcpy(device.properties.deviceName, name, sizeof(name));
+  device.properties.limits.maxImageDimension1D = 3;
+  device.properties.limits.maxSamplerLodBias = 3.5f;
+  device.properties.limits.bufferImageGranularity = 0x1ffffffffull;
+  device.properties.limits.maxViewportDimensions[0] = 1;
+  device.properties.limits.maxViewportDimensions[1] = 2;
   VkFormatProperties format_props = {
       VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT,
       VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT,
       VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT};
-  device_props.formats.insert(
-      std::make_pair(VK_FORMAT_R8_UNORM, format_props));
-  device_props.formats.insert(
-      std::make_pair(VK_FORMAT_R8G8_UNORM, format_props));
-  std::string json = VkJsonAllPropertiesToJson(device_props);
+  device.formats.insert(std::make_pair(VK_FORMAT_R8_UNORM, format_props));
+  device.formats.insert(std::make_pair(VK_FORMAT_R8G8_UNORM, format_props));
+
+  std::string json = VkJsonInstanceToJson(instance);
   std::cout << json << std::endl;
 
-  VkJsonAllProperties device_props2;
-  result = VkJsonAllPropertiesFromJson(json, &device_props2, &errors);
+  VkJsonInstance instance2;
+  result = VkJsonInstanceFromJson(json, &instance2, &errors);
   EXPECT(result);
   if (!result)
     std::cout << "Error: " << errors << std::endl;
+  const VkJsonDevice& device2 = instance2.devices.at(0);
 
-  EXPECT(!memcmp(&device_props.properties,
-                 &device_props2.properties,
-                 sizeof(device_props.properties)));
-  for (auto& kv : device_props.formats) {
-    auto it = device_props2.formats.find(kv.first);
-    EXPECT(it != device_props2.formats.end());
+  EXPECT(!memcmp(&device.properties, &device2.properties,
+                 sizeof(device.properties)));
+  for (auto& kv : device.formats) {
+    auto it = device2.formats.find(kv.first);
+    EXPECT(it != device2.formats.end());
     EXPECT(!memcmp(&kv.second, &it->second, sizeof(kv.second)));
   }
 
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index 2c3b245..a4d2b21 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -17,6 +17,7 @@
     loader.c
     loader.h
     vk_loader_platform.h
+    vk_loader_layer.h
     trampoline.c
     wsi.c
     wsi.h
@@ -37,8 +38,14 @@
 set (LOADER_SRCS ${NORMAL_LOADER_SRCS} ${OPT_LOADER_SRCS})
 
 if (WIN32)
-    set(CMAKE_C_FLAGS_DEBUG "-MTd")
-    set(CMAKE_C_FLAGS_RELEASE "-MT")
+    # Use static MSVCRT libraries
+    foreach(configuration in CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO
+                             CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+        if(${configuration} MATCHES "/MD")
+            string(REGEX REPLACE "/MD" "/MT" ${configuration} "${${configuration}}")
+        endif()
+    endforeach()
+
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS")
     # Build dev_ext_trampoline.c with -O2 to allow tail-call optimization.
     # Build other C files with normal options
@@ -56,6 +63,7 @@
     add_library(VKstatic.${MAJOR} STATIC $<TARGET_OBJECTS:loader-opt> $<TARGET_OBJECTS:loader-norm>)
     set_target_properties(VKstatic.${MAJOR} PROPERTIES OUTPUT_NAME VKstatic.${MAJOR})
     target_link_libraries(vulkan-${MAJOR} shlwapi)
+    target_link_libraries(VKstatic.${MAJOR} shlwapi)
     if (CMAKE_GENERATOR MATCHES "^Visual Studio.*")
         file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>/vulkan-${MAJOR}.dll COPY_SRC_PATH)
         file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../demos/$<CONFIGURATION>/ COPY_DST_PATH)
@@ -74,6 +82,6 @@
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
 
     add_library(vulkan SHARED ${LOADER_SRCS})
-    set_target_properties(vulkan PROPERTIES SOVERSION "1" VERSION "1.0.13")
+    set_target_properties(vulkan PROPERTIES SOVERSION "1" VERSION "1.0.21")
     target_link_libraries(vulkan -ldl -lpthread -lm)
 endif()
diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md
index 4a986cd..375a263 100644
--- a/loader/LoaderAndLayerInterface.md
+++ b/loader/LoaderAndLayerInterface.md
@@ -1,24 +1,25 @@
 # Vulkan Loader Specification and Architecture Overview
 
+<br/>
 
-Goals of this document
-----------------------
+## Goals of this document ##
 
 Specify necessary functions and expected behavior of interface between the
 loader library and ICDs and layers for Windows, Linux and Android based
 systems. Also describe the application visible behaviors of the loader.
 
-Audience
---------
+<br/>
 
-Application, Vulkan driver and Vulkan layer developers.
+## Audience ##
 
-Any developers interested in understanding more about loader and layer behavior
-and architecture.
+This document is primarily targeted at Vulkan application, driver and layer developers.
+However, it can also be used by any developer interested in understanding more about
+how the Vulkan loader and layers interact.
+
+<br/>
 
 
-Loader goals
-------------
+## Loader goals ##
 
 -   Support multiple ICDs (Installable Client Drivers) to co-exist on a system
 without interfering with each other.
@@ -29,39 +30,46 @@
 -   Negligible performance cost for an application calling through the loader
 to an ICD entry point.
 
-Architectural overview of layers and loader
--------------------------------------------
+<br/>
 
-Vulkan is a layered architecture. Layers can hook (intercept) Vulkan commands to
-achieve various functionality that a Vulkan driver (aka ICD) or loader doesn’t
-support. Functionality such as Vulkan API tracing and debugging, API usage
-validation, and other tools such as framebuffer overlays are all natural
-candidates for Vulkan layers. Layers are implemented as libraries that are
-inserted between the application and the driver.
+## Architectural overview of layers and loader ##
 
-Not only is Vulkan a layered architecture but it also supports multiple GPUs
-and their drivers. Vulkan commands called by an application may wind up calling
-into a diverse set of modules: loader, layers, and ICDs. The loader is critical
-to managing the proper dispatching of Vulkan commands to the appropriate set of
-layers and ICDs. The Vulkan object model allows the loader to insert layers
-into a call chain so the layers can process Vulkan commands prior to the
-ICD being called.
+Vulkan is a layered architecture placing the Application on one end, the
+ICDs on the other, and the loader and some number of layers in between.
+
+Layers are implemented as libraries that can be enabled in different ways
+(including by application request) and loaded during CreateInstance.  Each
+layer can chooses to hook (intercept) any Vulkan commands which in turn
+can be ignored, augmented, or simply passed along.  A layer may also
+expose functionality not available in the loader or any ICD.  Some examples
+of this include: the ability to perform Vulkan API tracing and debugging,
+validate API usage, or overlay additional content on the applications surfaces.
+
+The loader is responsible for working with the various layers as well as
+supporting multiple GPUs and their drivers.  Any Vulkan command may
+wind up calling into a diverse set of modules: loader, layers, and ICDs.
+The loader is critical to managing the proper dispatching of Vulkan
+commands to the appropriate set of layers and ICDs. The Vulkan object
+model allows the loader to insert layers into a call chain so that the layers
+can process Vulkan commands prior to the ICD being called.
 
 Vulkan uses an object model to control the scope of a particular action /
 operation.  The object to be acted on is always the first parameter of a Vulkan
-call and is a dispatchable object (see Vulkan specification section 2.2 Object
+call and is a dispatchable object (see Vulkan specification section 2.3 Object
 Model).  Under the covers, the dispatchable object handle is a pointer to a
-structure that contains a pointer to a dispatch table maintained by the loader.
-This dispatch table contains pointers to the Vulkan functions appropriate to
-that object. There are two types of dispatch tables the loader maintains,
-Instance and Device. I.e. a VkInstance object’s dispatch table will point to Vulkan
-functions such as vkEnumeratePhysicalDevices, vkDestroyInstance,
-vkCreateInstance, etc. Instance functions take a VkInstance or VkPhysicalDevice as
-their first argument.
+structure, which in turn, contains a pointer to a dispatch table maintained by
+the loader.  This dispatch table contains pointers to the Vulkan functions appropriate to
+that object.
 
-Device objects have a separate dispatch table containing the appropriate
-function pointers. The device dispatch table is used for all functions that
-take a VkDevice, VkQueue or VkCommandBuffer as their first argument.
+There are two types of dispatch tables the loader maintains:
+-  **Instance Dispatch Table**
+  - Contains any function that takes a VkInstance or VkPhysicalDevice as their first parameter
+    - vkEnumeratePhysicalDevices
+    - vkDestroyInstance
+    - vkCreateInstance
+    - ...
+-  **Device Dispatch Table**
+  - Contains any function that takes a VkDevice, VkQueue or VkCommandBuffer as their first parameter
 
 These instance and device dispatch tables are constructed when the application
 calls vkCreateInstance and vkCreateDevice. At that time the application and/or
@@ -73,8 +81,8 @@
 
 For example, the diagram below represents what happens in the call chain for
 vkCreateInstance. After initializing the chain, the loader will call into the
-first layer’s vkCreateInstance which will call the next finally terminating in
-the loader again where this function calls every ICD’s vkCreateInstance and
+first layer's vkCreateInstance which will call the next finally terminating in
+the loader again where this function calls every ICD's vkCreateInstance and
 saves the results. This allows every enabled layer for this chain to set up
 what it needs based on the VkInstanceCreateInfo structure from the application.
 ![Instance call chain](instance_call_chain.png)
@@ -90,10 +98,11 @@
 instance) can skip intercepting any given Vulkan entry point.
 ![Chain skipping layers](chain_skipping_layers.png)
 
-Application interface to loader
--------------------------------
+<br/>
 
-In this section we’ll discuss how an application interacts with the loader.
+## Application interface to loader ##
+
+In this section we'll discuss how an application interacts with the loader.
 
 -   Linking to loader library for core and WSI extension symbols.
 
@@ -116,7 +125,7 @@
 
 Applications are not required to link directly to the loader library, instead
 they can use the appropriate platform specific dynamic symbol lookup on the
-loader library to initialize the application’s own dispatch table. This allows
+loader library to initialize the application's own dispatch table. This allows
 an application to fail gracefully if the loader cannot be found, and it
 provides the fastest mechanism for the application to call Vulkan functions. An
 application will only need to query (via system calls such as dlsym()) the
@@ -134,10 +143,11 @@
 guaranteed for all versions with the same major number (e.g. 1.0 and 1.1). On
 Windows, the loader library encodes the ABI version in its name such that
 multiple ABI incompatible versions of the loader can peacefully coexist on a
-given system. The Vulkan loader library file name is “vulkan-&lt;ABI
-version&gt;.dll”. For example, for Vulkan version 1.X on Windows the library
+given system. The Vulkan loader library file name is "vulkan-<ABI
+version>.dll". For example, for Vulkan version 1.X on Windows the library
 filename is vulkan-1.dll. And this library file can typically be found in the
-windows/system32 directory.
+windows/system32 directory (on 64-bit Windows installs, the 32-bit version of
+the loader with the same name can be found in the windows/sysWOW64 directory).
 
 For Linux, shared libraries are versioned based on a suffix. Thus, the ABI
 number is not encoded in the base of the library filename as on Windows. On
@@ -145,30 +155,39 @@
 just link to the name vulkan (libvulkan.so).  A specific Vulkan ABI version can
 also be linked to by applications (e.g. libvulkan.so.1).
 
+####Layer Usage
+
 Applications desiring Vulkan functionality beyond what the core API offers may
-use various layers or extensions. A layer cannot add new or modify existing
-Vulkan commands, but may offer extensions that do. A common use of layers is
-for API validation. A developer can use validation layers during application
-development, but during production the layers can be disabled by the
-application. Thus, eliminating the overhead of validating the application's
-usage of the API. Layers discovered by the loader are reported to the
-application via vkEnumerateInstanceLayerProperties.
-Layers are enabled at vkCreateInstance and are active for all Vulkan commands
-that using the given VkIstance and any of it's child objects.
-For example, the ppEnabledLayerNames array in the
-VkInstanceCreateInfo structure is used by the application to list the
-layer names to be enabled at vkCreateInstance. At vkCreateInstance and
-vkCreateDevice, the loader will construct call chains that include the
-application specified (enabled) layers.  vkCreateDevice will use the layers
-specified at vkCreateInstance. vkEnumerateDeviceLayerProperties and
-device layers are deprecated.  Order is important in the
+use various layers or extensions. A layer cannot introduce new Vulkan API
+entry-points not exposed in Vulkan.h, but may offer extensions that do. A
+common use of layers is for API validation which can be enabled by loading the
+layer during application development, but not loading the layer for application
+release. This eliminates the overhead of validating the application's
+usage of the API, something that wasn't available on some previous graphics
+APIs.
+
+Layers discovered by the loader are reported to the application via
+vkEnumerateInstanceLayerProperties.  Layers are enabled at vkCreateInstance
+and are active for all Vulkan commands using the given VkInstance and any
+of it's child objects.  For example, the ppEnabledLayerNames array in the
+VkInstanceCreateInfo structure is used by the application to list the layer
+names to be enabled at vkCreateInstance. At vkCreateInstance and
+vkCreateDevice, the loader will construct call chains that include the application
+specified (enabled) layers.  Order is important in the
 ppEnabledLayerNames array; array element 0 is the topmost (closest to the
 application) layer inserted in the chain and the last array element is closest
 to the driver.
 
+**NOTE**: vkCreateDevice originally was able to select layers in a
+similar manner to vkCreateInstance.  This lead to the concept of "instance
+layers" and "device layers".  It was decided by Khronos to deprecate the
+"device layer" functionality and only consider "instance layers".
+Therefore, vkCreateDevice will use the layers specified at vkCreateInstance.
+Additionally, vkEnumerateDeviceLayerProperties has been deprecated.  
+
 Developers may want to enable layers that are not enabled by the given
 application they are using. On Linux and Windows, the environment variable
-“VK\_INSTANCE\_LAYERS” can be used to enable
+"VK\_INSTANCE\_LAYERS" can be used to enable
 additional layers which are not specified (enabled) by the application at
 vkCreateInstance. VK\_INSTANCE\_LAYERS is a colon
 (Linux)/semi-colon (Windows) separated list of layer names to enable. Order is
@@ -189,6 +208,8 @@
 
 ```
 
+#### Implicit vs Explicit Layers
+
 Some platforms, including Linux and Windows, support layers which are enabled
 automatically by the loader rather than explicitly by the application (or via
 environment variable). Explicit layers are those layers enabled by the
@@ -200,10 +221,20 @@
 Explicitly enabling a layer that is implicitly enabled has no additional
 effect: the layer will still be enabled implicitly by the loader.
 
+Implicit layers have an additional requirement over explicit layers in that they
+require being able to be disabled by an environmental variable.  This is due
+to the fact that they are not visible to the application and could cause issues.
+A good principle to keep in mind would be to define both an enable and disable
+environment variable so the users can deterministicly enable the functionality.
+On Desktop platforms (Windows and Linux), these enable/disable settings are
+defined in the layer's JSON file.
+
 Extensions are optional functionality provided by a layer, the loader or an
 ICD. Extensions can modify the behavior of the Vulkan API and need to be
 specified and registered with Khronos.
 
+#### Instance/Device Extensions
+
 Instance extensions can be discovered via
 vkEnumerateInstanceExtensionProperties. Device extensions can be discovered via
 vkEnumerateDeviceExtensionProperties. The loader discovers and aggregates all
@@ -230,8 +261,8 @@
 VkGetDeviceProcAddr is particularly interesting because it will provide the
 most efficient way to call into the ICD. For example, the diagram below shows
 what could happen if the application were to use vkGetDeviceProcAddr for the
-function “vkGetDeviceQueue” and “vkDestroyDevice” but not “vkAllocateMemory”.
-The resulting function pointer (fpGetDeviceQueue) would be the ICD’s entry
+function "vkGetDeviceQueue" and "vkDestroyDevice" but not "vkAllocateMemory".
+The resulting function pointer (fpGetDeviceQueue) would be the ICD's entry
 point if the loader and any enabled layers do not need to see that call. Even
 if an enabled layer intercepts the call (e.g. vkDestroyDevice) the loader
 trampoline code is skipped for function pointers obtained via
@@ -242,9 +273,70 @@
 
 ![Get*ProcAddr efficiency](get_proc_addr.png)
 
+##### WSI Extensions
 
-Vulkan Installable Client Driver interface with the loader
-----------------------------------------------------------
+Khronos approved WSI extensions are available and provide Windows System Integration
+support for various execution environments. It is important to understand that some WSI
+extensions are valid for all targets, but others are particular to a given execution
+environment (and loader). This desktop loader (currently targeting Windows and Linux)
+only enables those WSI extensions that are appropriate to the current environment.
+For the most part, the selection is done in the loader using  compile-time preprocessor
+flags. All versions of the desktop loader currently expose at least the following WSI
+extension support:
+- VK_KHR_surface
+- VK_KHR_swapchain
+- VK_KHR_display
+
+In addition, each of the following OS targets for the loader support target-specific extensions:
+- **Windows** : VK_KHR_win32_surface
+- **Linux (default)** : VK_KHR_xcb_surface and VK_KHR_xlib_surface
+- **Linux (Wayland build)** : VK_KHR_wayland_surface
+- **Linux (Mir build)** : VK_KHR_mir_surface
+
+**NOTE:** Wayland and Mir targets are not fully supported at this time and should be considered
+alpha quality.
+
+It is important to understand that while the loader may support the various entry-points
+for these extensions, there is a hand-shake required to actually use them:
+* At least one physical device must support the extension(s)
+* The application must select such a physical device
+* The application must request the extension(s) be enabled while creating the instance or logical device (This depends on whether or not the given extension works with an instance or a device).
+* The instance and/or logical device creation must succeed.
+
+Only then can you expect to properly use a WSI extension in your Vulkan program.
+
+##### New Extensions
+
+With the ability to expand Vulkan so easily, extensions will be created that the loader knows
+nothing about.  If the extension is a device extension, the loader will pass the unknown
+entry-point down the device call chain ending with the appropriate ICD entry-points.
+However, if the extension is an instance extension, the loader will fail to load it.
+
+*But why doesn't the loader support unknown instance extensions?*
+<br/>
+Let's look again at the Instance call chain:
+![Instance call chain](instance_call_chain.png)
+
+Notice that for a normal instance function call, the loader has to handle passing along the
+function call to the available ICDs.  If the loader has no idea of the parameters or return
+value of the instance call, it can't properly pass information along to the ICDs.
+There may be ways to do this, which will be explored in the future.  However, for now, this
+loader does not support any unknown instance extensions.
+
+Because the device call-chain does not pass through the loader terminator, this is not
+a problem for device extensions.  Instead, device extensions terminate directly in the
+ICD they are associated with.
+
+*Is this a big problem?*
+<br/>
+No!  Most extension functionality only affects a device and not an instance or a physical
+device.  Thus, the overwhelming majority of extensions will be device extensions rather than
+instance extensions.
+
+<br/>
+
+
+## Vulkan Installable Client Driver interface with the loader ##
 
 ### ICD discovery
 
@@ -266,6 +358,11 @@
 
 HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\Drivers
 
+On 64-bit Windows, when a 32-bit application is triggered, the loader
+will scan for 32-bit drivers in a separate area of the registry:
+
+HKEY\_LOCAL\_MACHINE\\SOFTWARE\\WOW6432Node\\Khronos\\Vulkan\\Drivers
+
 For each value in this key which has DWORD data set to 0, the loader opens the
 JSON format text information file (a.k.a. "manifest file") specified by the
 name of the value. Each name must be a full pathname to the text manifest file.
@@ -295,10 +392,10 @@
 The "file\_format\_version" specifies a major.minor.patch version number in
 case the format of the text information file changes in the future. If the same
 ICD shared library supports multiple, incompatible versions of text manifest
-file format versions, it must have multiple text info files (all of which may
+file format versions, it must have separate JSON files for each (all of which may
 point to the same shared library).
 
-The “api\_version” specifies the major.minor.patch version number of the Vulkan
+The "api\_version" specifies the major.minor.patch version number of the Vulkan
 API that the shared library (referenced by "library\_path") was built with.
 
 There are no rules about the name of the text information files (except the
@@ -410,7 +507,7 @@
 versions, it must have multiple manifest files (all of which may point to the
 same shared library).
 
-The “api\_version” specifies the major.minor.patch version number of the Vulkan
+The "api\_version" specifies the major.minor.patch version number of the Vulkan
 API that the shared library (referenced by "library\_path") was built with.
 
 The "/usr/share/vulkan/icd.d" directory is for ICDs that are installed from
@@ -478,12 +575,12 @@
 of "vulkan". Due to security policies in Android none of this can be modified
 under normal use.
 
+<br/>
 
-ICD interface requirements
-----------------------------------------
+## ICD interface requirements ##
 
 Generally, for all Vulkan commands issued by an application, the loader can be
-viewed as a pass through. That is, the loader generally doesn’t modified the
+viewed as a pass through. That is, the loader generally doesn't modify the
 commands or their parameters, but simply calls the ICDs entry point for that
 command. There are specific additional interface requirements an ICD needs to comply with that
 are over and above any requirements from the Vulkan specification including WSI extension specification.
@@ -515,7 +612,7 @@
 Similarly, if an ICD sees a call to vk\_icdGetInstanceProcAddr before a call to
 vk_icdGetLoaderICDInterfaceVersion then it knows that it's dealing with a legacy loader
 supporting version 0 or 1.
-Note if the loader calls vk\_icdGetInstanceProcAddr first it supports version 1,
+**Note** if the loader calls vk\_icdGetInstanceProcAddr first it supports at least version 1,
 otherwise the loader only supports version 0.
 
 The pSupportedVersion parameter is both an input and output parameter.
@@ -686,13 +783,15 @@
 respective libraries and does not use the json manifest files used
 by the Windows and Linux loaders.
 
-Vulkan layer interface with the loader
---------------------------------------
+<br/>
+
+## Vulkan layer interface with the loader ##
 
 ### Layer discovery
 
 #### Windows
 
+<a name="ManifestFileExample"></a>
 ##### Properly-Installed Layers
 
 In order to find properly-installed layers, the Vulkan loader will use a
@@ -732,107 +831,47 @@
 The Vulkan loader will open each info file to obtain information about the
 layer, including the name or pathname of a shared library (".dll") file.
 
-This manifest file is in the JSON format and contains the following
-information:
-
-- (required) "file\_format\_version" - same as for ICDs, except that the format
-version can vary independently for ICDs and layers.
-
-- (required) "name" - layer name
-
-- (required and deprecated) "type" - which layer chains should the layer be activated on.
-Distinct instance and device layers are deprecated; there are now just layers.
-Allowable values for type (both before and after deprecation) are "INSTANCE", "GLOBAL" and, "DEVICE."
-"DEVICE" layers are skipped over by the loader as if they were not found.
-Thus, layers must have a type of "GLOBAL" or "INSTANCE" for the loader to include the layer in it's discovery.
-
-- (required) "library\_path" - filename / full path / relative path to the
-library file
-
-- (required) "api\_version" - same as for ICDs.
-
-- (required) "implementation\_version" - layer version, a single number
-increasing with backward compatible changes.
-
-- (required) "description" - informative description of the layer.
-
-- (optional) "device\_extensions" or "instance\_extensions" - array of
-extension information as follows
-
-    - (required) extension "name" - Vulkan registered name
-
-    - (required) extension "spec\_version" - extension specification version, a
-single number, increasing with backward compatible changes.
-
-    - (required for device\_extensions with entry points) extension
-"entrypoints" - array of device extension entry points; not used for instance
-extensions
-
-- (sometimes required) "functions" - mapping list of function entry points. If
-multiple layers exist within the same shared library (or if a layer is in the
-same shared library as an ICD), this must be specified to allow each layer to
-have its own vkGet\*ProcAddr entry points that can be found by the loader. At
-this time, only the following two functions are required:
-
-    - "vkGetInstanceProcAddr" name
-
-    - "vkGetDeviceProcAddr" name
-
-- (optional for implicit layers) "enable\_environment" requirement(s) -
-environment variable and value required to enable an implicit layer. This
-environment variable (which should vary with each "version" of the layer, as in
-"ENABLE\_LAYER\_FOO\_1") must be set to the given value or else the implicit
-layer is not loaded. This is for application environments (e.g. Steam) which
-want to enable a layer(s) only for applications that they launch, and allows
-for applications run outside of an application environment to not get that
-implicit layer(s).
-
-- (required for implicit layers) "disable\_environment" requirement(s) -
-environment variable and value required to disable an implicit layer. Note: in
-rare cases of an application not working with an implicit layer, the
-application can set this environment variable (before calling Vulkan commands)
-in order to "blacklist" the layer. This environment variable (which should vary
-with each "version" of the layer, as in "DISABLE\_LAYER\_FOO\_1") must be set
-(not particularly to any value). If both the "enable\_environment" and
-"disable\_environment" variables are set, the implicit layer is disabled.
-
-For example:
+This manifest file is in the JSON format as shown in the following example.
+See the section [Layer Library Manifest File](#LayerLibraryManifestFile) for more information about each of the nodes in the JSON file.
 
 ```
 {
-"file_format_version" : "1.0.0",
-"layer": {
-    "name": "VK_LAYER_LUNARG_overlay",
-    "type": "INSTANCE",
-    "library_path": "vkOverlayLayer.dll"
-    "api_version" : "1.0.5",
-    "implementation_version" : "2",
-    "description" : "LunarG HUD layer",
-    "functions": {
-        "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr",
-        "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr"
-    },
-    "instance_extensions": [
-        {
-            "name": "VK_debug_report_EXT",
-            "spec_version": "1"
-        },
-        {
-            "name": "VK_VENDOR_DEBUG_X",
-            "spec_version": "3"
-         }
-    ],
-    "device_extensions": [
-        {
-            "name": "VK_DEBUG_MARKER_EXT",
-            "spec_version": "1",
-            "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"]
-        }
-    ],
-    "disable_environment": {
-        "DISABLE_LAYER_OVERLAY_1": ""
-    }
-}
+   "file_format_version" : "1.0.0",
+   "layer": {
+       "name": "VK_LAYER_LUNARG_overlay",
+       "type": "INSTANCE",
+       "library_path": "vkOverlayLayer.dll"
+       "api_version" : "1.0.5",
+       "implementation_version" : "2",
+       "description" : "LunarG HUD layer",
+       "functions": {
+           "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr",
+           "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr"
+       },
+       "instance_extensions": [
+           {
+               "name": "VK_EXT_debug_report",
+               "spec_version": "1"
+           },
+           {
+               "name": "VK_VENDOR_ext_x",
+               "spec_version": "3"
+            }
+       ],
+       "device_extensions": [
+           {
+               "name": "VK_EXT_debug_marker",
+               "spec_version": "1",
+               "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"]
+           }
+       ],
+       "enable_environment": {
+           "ENABLE_LAYER_OVERLAY_1": "1"
+       }
+       "disable_environment": {
+           "DISABLE_LAYER_OVERLAY_1": ""
+       }
+   }
 }
 ```
 
@@ -845,6 +884,34 @@
 library lives in the system's DLL search path (e.g. in the
 "C:\\Windows\\System32" folder).
 
+If defining multiple layers in a single JSON file prior to "file\_format\_version"
+1.0.1, you would simply define multiple "layer" objects.  However, this is not
+valid JSON syntax.  Instead, you should now define "file\_format\_version"
+1.0.1 (or newer) and use the new "layers" array object as seen in the
+following example:
+
+```
+{
+   "file_format_version" : "1.0.1",
+   "layers": [
+      {
+           "name": "VK_LAYER_layer_name1",
+           "type": "INSTANCE",
+           ...
+      },
+      {
+           "name": "VK_LAYER_layer_name2",
+           "type": "INSTANCE",
+           ...
+      }
+   ]
+}
+```
+
+You could use the "layers" array object to define a single layer, as long as
+your "file\_format\_version" is defined to at least 1.0.1.  It is functionally the
+same as using a single "layer" object.
+
 There are no rules about the name of the text files (except the .json suffix).
 
 There are no rules about the name of the layer shared library files.
@@ -903,104 +970,47 @@
 "/etc/vulkan/\*\_layer.d" directories are for layers that are installed from
 non-Linux-distribution-provided packages.
 
-The information file is in the JSON format and contains the following
-information:
+This manifest file is in the JSON format as shown in the following example.
+See the section [Layer Library Manifest File](#LayerLibraryManifestFile) for more information about each of the nodes in the JSON file.
 
-- (required) "file\_format\_version" – same as for ICDs, except that the format
-version can vary independently for ICDs and layers.
-
-- (required) "name" - layer name
-
-- (required and deprecated) "type" - which layer chains should the layer be activated on.
-Distinct instance and device layers are deprecated; there are now just layers.
-Allowable values for type (both before and after deprecation) are "INSTANCE", "GLOBAL" and, "DEVICE."
-"DEVICE" layers are skipped over by the loader as if they were not found.
-Thus, layers must have a type of "GLOBAL" or "INSTANCE" for the loader to include the layer in it's discovery.
-
-- (required) "library\_path" - filename / full path / relative path to the text
-file
-
-- (required) "api\_version" – same as for ICDs.
-
-- (required) "implementation\_version" – layer version, a single number
-increasing with backward compatible changes.
-
-- (required) "description" – informative description of the layer.
-
-- (optional) "device\_extensions" or "instance\_extensions" - array of
-extension information as follows
-
-    - (required) extension "name" - Vulkan registered name
-
-    - (required) extension "spec\_version" - extension specification version, a
-single number, increasing with backward compatible changes.
-
-    - (required for device extensions with entry points) extension
-"entrypoints" - array of device extension entry points; not used for instance
-extensions
-
-- (sometimes required) "functions" - mapping list of function entry points. If
-multiple layers exist within the same shared library (or if a layer is in the
-same shared library as an ICD), this must be specified to allow each layer to
-have its own vkGet\*ProcAddr entry points that can be found by the loader. At
-this time, only the following two functions are required:
-    - "vkGetInstanceProcAddr" name
-    - "vkGetDeviceProcAddr" name
-
-- (optional for implicit layers) "enable\_environment" requirement(s) -
-environment variable and value required to enable an implicit layer. This
-environment variable (which should vary with each "version" of the layer, as in
-"ENABLE\_LAYER\_FOO\_1") must be set to the given value or else the implicit
-layer is not loaded. This is for application environments (e.g. Steam) which
-want to enable a layer(s) only for applications that they launch, and allows
-for applications run outside of an application environment to not get that
-implicit layer(s).
-
-- (required for implicit layers) "disable\_environment" requirement(s) -
-environment variable and value required to disable an implicit layer. Note: in
-rare cases of an application not working with an implicit layer, the
-application can set this environment variable (before calling Vulkan commands)
-in order to "blacklist" the layer. This environment variable (which should vary
-with each "version" of the layer, as in "DISABLE\_LAYER\_FOO\_1") must be set
-(not particularly to any value). If both the "enable\_environment" and
-"disable\_environment" variables are set, the implicit layer is disabled.
-
-For example:
 ```
 {
-"file_format_version" : "1.0.0",
-"layer": {
-    "name": "VK_LAYER_LUNARG_overlay",
-    "type": "INSTANCE",
-    "library_path": "vkOverlayLayer.dll"
-    "api_version" : "1.0.5",
-    "implementation_version" : "2",
-    "description" : "LunarG HUD layer",
-    "functions": {
-        "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr",
-        "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr"
-    },
-    "instance_extensions": [
-        {
-            "name": "VK_debug_report_EXT",
-            "spec_version": "1"
-        },
-        {
-            "name": "VK_VENDOR_DEBUG_X",
-            "spec_version": "3"
-         }
-    ],
-    "device_extensions": [
-        {
-            "name": "VK_DEBUG_MARKER_EXT",
-            "spec_version": "1",
-            "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"]
-        }
-    ],
-    "disable_environment": {
-        "DISABLE_LAYER_OVERLAY_1": ""
-    }
-}
+   "file_format_version" : "1.0.0",
+   "layer": {
+       "name": "VK_LAYER_LUNARG_overlay",
+       "type": "INSTANCE",
+       "library_path": "libvkOverlayLayer.so"
+       "api_version" : "1.0.5",
+       "implementation_version" : "2",
+       "description" : "LunarG HUD layer",
+       "functions": {
+           "vkGetInstanceProcAddr": "OverlayLayer_GetInstanceProcAddr",
+           "vkGetDeviceProcAddr": "OverlayLayer_GetDeviceProcAddr"
+       },
+       "instance_extensions": [
+           {
+               "name": "VK_EXT_debug_report",
+               "spec_version": "1"
+           },
+           {
+               "name": "VK_VENDOR_ext_x",
+               "spec_version": "3"
+            }
+       ],
+       "device_extensions": [
+           {
+               "name": "VK_EXT_debug_marker",
+               "spec_version": "1",
+               "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"]
+           }
+       ],
+       "enable_environment": {
+           "ENABLE_LAYER_OVERLAY_1": "1"
+       },
+       "disable_environment": {
+           "DISABLE_LAYER_OVERLAY_1": ""
+       }
+   }
 }
 ```
 The "library\_path" specifies either a filename, a relative pathname, or a full
@@ -1044,8 +1054,9 @@
 An application enabled for debug has more options. It can enumerate and enable
 layers located in /data/local/vulkan/debug.
 
-Layer interface requirements
-------------------------------------------------------
+<br/>
+
+## Layer interface requirements ##
 
 #### Architectural interface overview
 
@@ -1092,7 +1103,7 @@
 #### Layer Library Interface
 
 A layer library is a container of layers.  This section defines an extensible
-manifest file interface or programming interface to discover layers contained in layer libraries.
+interface to discover layers contained in layer libraries.
 The extensible programming interface is used on Android only. For Windows and Linux,
 the layer manifest JSON files are used.
 
@@ -1136,17 +1147,28 @@
 extension names.  It may assume the layer names and extension names have been
 validated.
 
-`vkGetInstanceProcAddr` can intercept a command by returning a function
-pointer different from what would be returned through chaining.
+`vkGetInstanceProcAddr` intercepts a Vulkan command by returning a local entry point,
+otherwise it returns the value obtained by calling down the instance chain.
+    These commands must be intercepted
+   - vkGetInstanceProcAddr
+   - vkCreateInstance
+   - vkCreateDevice (only required for any device-level chaining)
 
-`vkGetDeviceProcAddr` can intercept a command by returning a function pointer
-different from what would be returned through chaining.
+   For compatibility with older layer libraries,
+   - when `pName` is `vkCreateDevice`, it ignores `instance`.
+
+`vkGetDeviceProcAddr` intercepts a Vulkan command by returning a local entry point,
+otherwise it returns the value obtained by calling down the device chain.
+
+The specification requires `NULL` to be returned from `vkGetInstanceProcAddr` and
+`vkGetDeviceProcAddr` for disabled commands.  A layer may return `NULL` itself or
+rely on the following layers to do so.
 
 [\*]: The intention is for layers to have a well-defined baseline behavior.
 Some of the conventions or rules, for example, may be considered abuses of the
 specification.
 
-###### Layer Library Interface Version 0 (Android)
+##### Layer Library API Version 0
 
 A layer library supporting interface version 0 must define and export these
 introspection functions, unrelated to any Vulkan command despite the names,
@@ -1178,74 +1200,81 @@
 
 The introspection functions are not used by the desktop loader.
 
-It must also define and export these functions:
+It must also define and export these functions one for each layer in the library:
 
- - `<layerName>GetInstanceProcAddr` behaves as if `<layerName>`'s
-   `vkGetInstanceProcAddr` is called, except
-
-   - when `pName` is `vkEnumerateInstanceLayerProperties`,
-     `vkEnumerateInstanceExtensionProperties`, or
-     `vkEnumerateDeviceLayerProperties` (but _not_
-     `vkEnumerateDeviceExtensionProperties`), it returns a function pointer to
-     the corresponding introspection function defined by this interface.
-   - when `pName` is `vkGetInstanceProcAddr`, it returns a function pointer
-     to itself.
-
-   For compatibility with older layer libraries,
-
-   - when `pName` is `vkCreateDevice`, it ignores `instance`.
-   - when `pName` is a device command defined by Vulkan 1.0 or
-     `VK_KHR_swapchain` (but _not_ other device commands), it may chain to
-     other layers without intercepting.  A loader should avoid querying such
-     device commands.
+ - `<layerName>GetInstanceProcAddr(instance, pName)` behaves identically to a layer's vkGetInstanceProcAddr except it is exported.
 
    When a layer library contains only one layer, this function may
    alternatively be named `vkGetInstanceProcAddr`.
 
- - `<layerName>GetDeviceProcAddr` behaves as if `<layerName>`'s
-   `vkGetDeviceProcAddr` is called.
+ - `<layerName>GetDeviceProcAddr`  behaves identically to a layer's vkGetDeviceProcAddr except it is exported.
 
    When a layer library contains only one layer, this function may
    alternatively be named `vkGetDeviceProcAddr`.
 
-All contained layers must support [`vk_layer.h`][].  They do not need to
-implement commands that are not queryable.  They are recommended not to export
-any command.
+All layers contained within a library must support [`vk_layer.h`][].  They do not need to
+implement commands that they do not intercept.  They are recommended not to export
+any commands.
 
-###### Layer Library Interface Version 0 (Windows and Linux)
+<a name="LayerLibraryManifestFile"></a>
+##### Layer Library Manifest File Version 0
 On Windows and Linux (desktop), the loader uses manifest files to discover
 layer libraries and layers.  The desktop loader doesn't directly query the
-layer library except during chaining.  On Android, the loader queries the layer libraries directly as outlined above.
+layer library except during chaining.
+On Android, the loader queries the layer libraries via the introspection functions as outlined above.
 
 The layer libraries and the manifest files must be kept in sync.
 
-The following table associates the desktop JSON nodes with the Android layer library queries. It also indicates requirements.
+The following table associates the desktop JSON nodes with the layer library introspection queries. It also indicates requirements.
 
-| Property | JSON node | Android library query | Notes |
+| Property | JSON node | Introspection query | Notes |
 |----------|-----------|-----------------------|-------|
-| layers in library | layer | vkEnumerateInstanceLayerProperties | one node required for each layer in the library |
-|layer name | name | vkEnumerateInstanceLayerProperties | one node is required |
-| layer type | type | vkEnumerateInstanceLayerProperties | one node is required (deprecated) |
+| file version | file_format_version | N/A | one node required per JSON file |
+| layers in library | layer | vkEnumerateInstanceLayerProperties | one node required per layer |
+| layer name | name | vkEnumerateInstanceLayerProperties | one node is required |
+| layer type | type | vkEnumerate*LayerProperties | see Note 1 |
 | library location | library_path | N/A | one node is required |
 | vulkan spec version | api_version | vkEnumerateInstanceLayerProperties | one node is required |
-| layer implementation version | api_version | vkEnumerateInstanceLayerProperties | one node is required |
+| layer implementation version | api_version | vkEnumerateInstanceLayerProperties | see Note 2 |
 | layer description | description | vkEnumerateInstanceLayerProperties | one node is required |
-| chaining functions | functions | vkGet*ProcAddr | see Note 1 |
-| instance extensions | instance_extensions | vkEnumerateInstanceExtensionProperties | see Note 2 |
-| device extensions | device_extensions | vkEnumerateDeviceExtensionProperties | see Note 3 |
+| chaining functions | functions | vkGet*ProcAddr | see Note 3 |
+| instance extensions | instance_extensions | vkEnumerateInstanceExtensionProperties | see Note 4 |
+| device extensions | device_extensions | vkEnumerateDeviceExtensionProperties | see Note 5 |
+| enable implicit | enable_environment | N/A | See Note 6 |
+| disable implicit | enable_environment | N/A | See Note 7 |
 
-Note 1: The "functions" node is required if the layer is using alternative
+"file\_format\_version" is used to indicate the valid JSON syntax of the file.
+As nodes are added or deleted which would change the parsing of this file,
+the file_format_version should change. This version
+is NOT the same as the layer library interface version. The interface version is a superset
+of the "file_format_version" and includes the semantics of the nodes in the JSON file.
+For interface version 0 the file format version must be "1.0.0"
+
+Note 1: Prior to deprecation, the "type" node was used to indicate which layer chain(s)
+to activate the layer upon: instance, device, or both.
+Distinct instance and device layers are deprecated; there are now just layers.
+Allowable values for type (both before and after deprecation) are "INSTANCE", "GLOBAL" and, "DEVICE."
+"DEVICE" layers are skipped over by the loader as if they were not found.
+Thus, layers must have a type of "GLOBAL" or "INSTANCE" for the loader to include the layer in the enumerated instance layer list.
+
+"library\_path" is the filename, full path, or relative path to the library file.
+See [Manifest File Example](#ManifestFileExample) section for more details.
+
+Note 2: One "implementation\_version" node is required per layer. This node gives the layer version, a single number
+increasing with backward uncompatible changes.
+
+Note 3: The "functions" node is required if the layer is using alternative
 names for vkGetInstanceProcAddr or vkGetDeviceProcAddr. vkGetInstanceProcAddr and vkGetDeviceProcAddr
-are required for all layers. See further requirements below.
+are required for all layers. See further requirements in the Layer Library API section above.
 
-Note 2: One "instance_extensions" node with an array of 1 or more elements
+Note 4: One "instance_extensions" node with an array of one or more elements
 required if any instance
 extensions are supported by a layer, otherwise the node is optional.  Each
 element of the array must have the nodes "name" and "spec_version" which
 correspond to  VkExtensionProperties "extensionName" and "specVersion"
 respectively.
 
-Note 3: One "device_extensions" node with an array of 1 or more elements
+Note 5: One "device_extensions" node with an array of one or more elements
 required if any device
 extensions are supported by a layer, otherwise the node is optional.  Each
 element of the array must have the nodes "name" and "spec_version" which
@@ -1255,52 +1284,39 @@
 otherwise this node is not required.
 The "entrypoint" node is an array of the names of all entrypoints added by the
 supported extension.
+```
+    "device_extensions": [
+        {
+            "name": "VK_EXT_debug_marker",
+            "spec_version": "1",
+            "entrypoints": ["vkCmdDbgMarkerBegin", "vkCmdDbgMarkerEnd"]
+        }
+ ```
 
-The manifest file nodes "file_format_version", "disable_environment", and
-"enable_environment" have no corresponding equivalent in the Vulkan API nor
-in the Android layer library interface.
+Note 6: The "enable\_environment" node is only for implicit layers only. It is optional for implicit layers.
+This node gives an environment variable and value required to enable an implicit layer. This
+environment variable (which should vary with each "version" of the layer) must be set to the
+given value or else the implicit layer is not loaded. This is for application environments (e.g. Steam) which
+want to enable a layer(s) only for applications that they launch, and allows
+for applications run outside of an application environment to not get that
+implicit layer(s).
 
-"file_format_version" is used to indicate the valid JSON syntax of the file.
-As nodes are added or deleted which would change the parsing of this file,
-the file_format_version should change. This version
-is NOT the same as the interface version. The interface version is a superset
-of the "file_format_version" and includes the semantics of the nodes in the JSON file.  For interface version 0 the file format version must be "1.0.0"
+Note 7: The "disable\_environment" node is only for implicit layers only. It is required for implicit layers.
+This node gives an environment variable and value required to disable an implicit layer. In
+rare cases of an application not working with an implicit layer, the
+application can set this environment variable (before calling Vulkan commands)
+in order to "blacklist" the layer. This environment variable (which should vary
+with each "version" of the layer) must be set (not particularly to any value).
+If both the "enable\_environment" and
+"disable\_environment" variables are set, the implicit layer is disabled.
 
-"disable_environment" (required) and "enable_evironment" (optional) are for implicit layers as previously described.
-
-vkGetInstanceProcAddr requirements:
--Irregardless of the name, this function must be implemented and exported in the library for all  layers.
--This function must return the local entry points for all instance level Vulkan commands it intercepts.
-At a minimum, this includes vkGetInstanceProcAddr and vkCreateInstance.
-Optionally, this function may return intercepted device level
-Vulkan commands.
--Vulkan commands that a layer doesn't intercept must be passed to the next
-entity in the chain. That is, the next layer/ICD's GetInstanceProcAddr must be called.
--Currently this function must be able to handle a VkInstance parameter equal
-to NULL for instance level commands it intercepts including vkCreateDevice.
-
-VkGetDeviceProcAddr requirements:
--Irregardless of the name, this function must be implemented and exported in the library for all  layers.
--This function must return the local entry points for all device level Vulkan
-commands it intercepts. At a minimum, this includes vkGetDeviceProcAddr and vkCreateDevice.
--Vulkan commands that a layer doesn't intercept must be passed to the next
-entity in the chain. That is, the next layer/ICD's GetDeviceProcAddr must be called.
-
-There are no requirements on the names of the intercepting functions a layer
-implements except those listed above for vkGetInstanceProcAddr and
-vkGetDeviceProcAddr. Layers do not need to implement commands that are not going to be intercepted.
-
-All layers within a library must support [`vk_layer.h`][].
-[`vk_layer.h`]: ../include/vulkan/vk_layer.h
-
-#### Layer intercept requirements
+#### Layer Dispatch Interface Version 0
+##### Layer intercept requirements
 
 - Layers intercept a Vulkan command by defining a C/C++ function with signature
 identical to the Vulkan API for that command.
 - A layer must intercept at least vkGetInstanceProcAddr and
 vkCreateInstance.  Additionally, a layer would also intercept vkGetDeviceProcAddr and vkCreateDevice to participate in the device chain.
-- Other than the two vkGet*ProcAddr, all other functions intercepted by a layer
-need NOT be exported by the layer.
 - For any Vulkan command a layer intercepts which has a non-void return value,
 an appropriate value must be returned by the layer intercept function.
 - The layer intercept function must call down the chain to the corresponding
@@ -1314,7 +1330,7 @@
 vkQueueSubmit.  Any additional calls inserted by a layer must be on the same
 chain. They should call down the chain.
 
-#### Distributed dispatching requirements
+##### Distributed dispatching requirements
 
 - For each entry point a layer intercepts, it must keep track of the entry
 point residing in the next entity in the chain it will call down into. In other
@@ -1332,7 +1348,7 @@
 vkGetDeviceProcAddr to call down the chain for unknown (i.e. non-intercepted)
 functions.
 
-#### Layer dispatch initialization
+##### Layer dispatch initialization
 
 - A layer initializes its instance dispatch table within its vkCreateInstance
 function.
@@ -1374,7 +1390,7 @@
 Get*ProcAddr function once for each Vulkan command needed in your dispatch
 table
 
-#### Example code for CreateInstance
+##### Example code for CreateInstance
 
 ```cpp
 VkResult vkCreateInstance(
@@ -1389,7 +1405,7 @@
     PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
         chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
     PFN_vkCreateInstance fpCreateInstance =
-        (PFN_vkCreateInstance)fpGetInstanceProcAddr(*pInstance, "vkCreateInstance");
+        (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
     if (fpCreateInstance == NULL) {
         return VK_ERROR_INITIALIZATION_FAILED;
     }
@@ -1415,7 +1431,7 @@
 }
 ```
 
-#### Example code for CreateDevice
+##### Example code for CreateDevice
 
 ```cpp
 VkResult 
diff --git a/loader/cJSON.c b/loader/cJSON.c
index f28eadb..e7266c3 100644
--- a/loader/cJSON.c
+++ b/loader/cJSON.c
@@ -88,6 +88,10 @@
     }
 }
 
+void cJSON_Free(void *p) {
+    cJSON_free(p);
+}
+
 /* Parse the input text to generate a number, and populate the result into item.
  */
 static const char *parse_number(cJSON *item, const char *num) {
@@ -423,7 +427,6 @@
         if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\')
             *ptr2++ = *ptr++;
         else {
-            *ptr2++ = '\\';
             switch (token = *ptr++) {
             case '\\':
                 *ptr2++ = '\\';
@@ -432,19 +435,19 @@
                 *ptr2++ = '\"';
                 break;
             case '\b':
-                *ptr2++ = 'b';
+                *ptr2++ = '\b';
                 break;
             case '\f':
-                *ptr2++ = 'f';
+                *ptr2++ = '\f';
                 break;
             case '\n':
-                *ptr2++ = 'n';
+                *ptr2++ = '\n';
                 break;
             case '\r':
-                *ptr2++ = 'r';
+                *ptr2++ = '\r';
                 break;
             case '\t':
-                *ptr2++ = 't';
+                *ptr2++ = '\t';
                 break;
             default:
                 sprintf(ptr2, "u%04x", token);
diff --git a/loader/cJSON.h b/loader/cJSON.h
index c6a57be..cab3051 100644
--- a/loader/cJSON.h
+++ b/loader/cJSON.h
@@ -84,6 +84,8 @@
 extern char *cJSON_PrintBuffered(cJSON *item, int prebuffer, int fmt);
 /* Delete a cJSON entity and all subentities. */
 extern void cJSON_Delete(cJSON *c);
+/* Delete an item allocated inside the JSON parser*/
+extern void cJSON_Free(void *p);
 
 /* Returns the number of items in an array (or object). */
 extern int cJSON_GetArraySize(cJSON *array);
diff --git a/loader/debug_report.c b/loader/debug_report.c
index c339c70..4da1413 100644
--- a/loader/debug_report.c
+++ b/loader/debug_report.c
@@ -66,12 +66,16 @@
                                const VkAllocationCallbacks *pAllocator,
                                VkDebugReportCallbackEXT callback) {
     VkLayerDbgFunctionNode *pNewDbgFuncNode;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+    {
+#else
     if (pAllocator != NULL) {
         pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(
             pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
-            sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+            sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     } else {
-        pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_heap_alloc(
+#endif
+        pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(
             inst, sizeof(VkLayerDbgFunctionNode),
             VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     }
@@ -137,10 +141,14 @@
             pPrev->pNext = pTrav->pNext;
             if (inst->DbgFunctionHead == pTrav)
                 inst->DbgFunctionHead = pTrav->pNext;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+            {
+#else
             if (pAllocator != NULL) {
                 pAllocator->pfnFree(pAllocator->pUserData, pTrav);
             } else {
-                loader_heap_free(inst, pTrav);
+#endif
+                loader_instance_heap_free(inst, pTrav);
             }
             break;
         }
@@ -159,6 +167,8 @@
     uint32_t *num_callbacks, VkDebugReportCallbackCreateInfoEXT **infos,
     VkDebugReportCallbackEXT **callbacks) {
     uint32_t n = *num_callbacks = 0;
+    VkDebugReportCallbackCreateInfoEXT *pInfos = NULL;
+    VkDebugReportCallbackEXT *pCallbacks = NULL;
 
     // NOTE: The loader is not using pAllocator, and so this function doesn't
     // either.
@@ -176,17 +186,38 @@
         return VK_SUCCESS;
     }
 
-    // 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
-    VkDebugReportCallbackCreateInfoEXT *pInfos = *infos =
-        ((VkDebugReportCallbackCreateInfoEXT *)malloc(
+// 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+    {
+#else
+    if (pAllocator != NULL) {
+        pInfos = *infos =
+            ((VkDebugReportCallbackCreateInfoEXT *)pAllocator->pfnAllocation(
+                pAllocator->pUserData,
+                n * sizeof(VkDebugReportCallbackCreateInfoEXT), sizeof(void *),
+                VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+    } else {
+#endif
+        pInfos = *infos = ((VkDebugReportCallbackCreateInfoEXT *)malloc(
             n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
+    }
     if (!pInfos) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
-    // 3rd, allocate memory for a unique handle for each callback:
-    VkDebugReportCallbackEXT *pCallbacks = *callbacks =
-        ((VkDebugReportCallbackEXT *)malloc(n *
-                                            sizeof(VkDebugReportCallbackEXT)));
+// 3rd, allocate memory for a unique handle for each callback:
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+    {
+#else
+    if (pAllocator != NULL) {
+        pCallbacks = *callbacks =
+            ((VkDebugReportCallbackEXT *)pAllocator->pfnAllocation(
+                pAllocator->pUserData, n * sizeof(VkDebugReportCallbackEXT),
+                sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+    } else {
+#endif
+        pCallbacks = *callbacks = ((VkDebugReportCallbackEXT *)malloc(
+            n * sizeof(VkDebugReportCallbackEXT)));
+    }
     if (!pCallbacks) {
         free(pInfos);
         return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -281,7 +312,21 @@
     VkResult res = VK_SUCCESS;
     uint32_t storage_idx;
 
-    icd_info = calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+    {
+#else
+    if (pAllocator != NULL) {
+        icd_info = ((VkDebugReportCallbackEXT *)pAllocator->pfnAllocation(
+            pAllocator->pUserData,
+            inst->total_icd_count * sizeof(VkDebugReportCallbackEXT),
+            sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+        memset(icd_info, 0,
+               inst->total_icd_count * sizeof(VkDebugReportCallbackEXT));
+    } else {
+#endif
+        icd_info =
+            calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
+    }
     if (!icd_info) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -328,10 +373,9 @@
  * This is the instance chain terminator function
  * for DestroyDebugReportCallback
  */
-VKAPI_ATTR void VKAPI_CALL
-terminator_DestroyDebugReportCallback(VkInstance instance,
-                                      VkDebugReportCallbackEXT callback,
-                                      const VkAllocationCallbacks *pAllocator) {
+VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallback(
+    VkInstance instance, VkDebugReportCallbackEXT callback,
+    const VkAllocationCallbacks *pAllocator) {
     uint32_t storage_idx;
     VkDebugReportCallbackEXT *icd_info;
     const struct loader_icd *icd;
@@ -356,11 +400,10 @@
  * This is the instance chain terminator function
  * for DebugReportMessage
  */
-VKAPI_ATTR void VKAPI_CALL
-terminator_DebugReportMessage(VkInstance instance, VkDebugReportFlagsEXT flags,
-                              VkDebugReportObjectTypeEXT objType,
-                              uint64_t object, size_t location, int32_t msgCode,
-                              const char *pLayerPrefix, const char *pMsg) {
+VKAPI_ATTR void VKAPI_CALL terminator_DebugReportMessage(
+    VkInstance instance, VkDebugReportFlagsEXT flags,
+    VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+    int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
     const struct loader_icd *icd;
 
     struct loader_instance *inst = (struct loader_instance *)instance;
diff --git a/loader/dirent_on_windows.c b/loader/dirent_on_windows.c
index e408224..6f78cf9 100644
--- a/loader/dirent_on_windows.c
+++ b/loader/dirent_on_windows.c
@@ -36,9 +36,9 @@
         const char *all = /* search pattern must end with suitable wildcard */
             strchr("/\\", name[base_length - 1]) ? "*" : "/*";
 
-        if ((dir = (DIR *)loader_tls_heap_alloc(sizeof *dir)) != 0 &&
-            (dir->name = (char *)loader_tls_heap_alloc(base_length +
-                                                       strlen(all) + 1)) != 0) {
+        if ((dir = (DIR *)loader_instance_tls_heap_alloc(sizeof *dir)) != 0 &&
+            (dir->name = (char *)loader_instance_tls_heap_alloc(
+                 base_length + strlen(all) + 1)) != 0) {
             strcat(strcpy(dir->name, name), all);
 
             if ((dir->handle =
@@ -46,13 +46,13 @@
                 dir->result.d_name = 0;
             } else /* rollback */
             {
-                loader_tls_heap_free(dir->name);
-                loader_tls_heap_free(dir);
+                loader_instance_tls_heap_free(dir->name);
+                loader_instance_tls_heap_free(dir);
                 dir = 0;
             }
         } else /* rollback */
         {
-            loader_tls_heap_free(dir);
+            loader_instance_tls_heap_free(dir);
             dir = 0;
             errno = ENOMEM;
         }
@@ -71,8 +71,8 @@
             result = _findclose(dir->handle);
         }
 
-        loader_tls_heap_free(dir->name);
-        loader_tls_heap_free(dir);
+        loader_instance_tls_heap_free(dir->name);
+        loader_instance_tls_heap_free(dir);
     }
 
     if (result == -1) /* map all errors to EBADF */
diff --git a/loader/loader.c b/loader/loader.c
index 151c7d7..6b22893 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -1,4 +1,4 @@
-/*
+/*
  *
  * Copyright (c) 2014-2016 The Khronos Group Inc.
  * Copyright (c) 2014-2016 Valve Corporation
@@ -159,66 +159,211 @@
 
 LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_init);
 
-void *loader_heap_alloc(const struct loader_instance *instance, size_t size,
-                        VkSystemAllocationScope alloc_scope) {
+void *loader_instance_heap_alloc(const struct loader_instance *instance,
+                                 size_t size,
+                                 VkSystemAllocationScope alloc_scope) {
+    void *pMemory = NULL;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+    {
+#else
     if (instance && instance->alloc_callbacks.pfnAllocation) {
-        /* TODO: What should default alignment be? 1, 4, 8, other? */
-        return instance->alloc_callbacks.pfnAllocation(
-            instance->alloc_callbacks.pUserData, size, sizeof(int),
+        /* These are internal structures, so it's best to align everything to
+         * the largest unit size which is the size of a uint64_t.
+        */
+        pMemory = instance->alloc_callbacks.pfnAllocation(
+            instance->alloc_callbacks.pUserData, size, sizeof(uint64_t),
             alloc_scope);
+    } else {
+#endif
+        pMemory = malloc(size);
     }
-    return malloc(size);
+    return pMemory;
 }
 
-void loader_heap_free(const struct loader_instance *instance, void *pMemory) {
-    if (pMemory == NULL)
-        return;
-    if (instance && instance->alloc_callbacks.pfnFree) {
-        instance->alloc_callbacks.pfnFree(instance->alloc_callbacks.pUserData,
-                                          pMemory);
-        return;
-    }
-    free(pMemory);
-}
-
-void *loader_heap_realloc(const struct loader_instance *instance, void *pMemory,
-                          size_t orig_size, size_t size,
-                          VkSystemAllocationScope alloc_scope) {
-    if (pMemory == NULL || orig_size == 0)
-        return loader_heap_alloc(instance, size, alloc_scope);
-    if (size == 0) {
-        loader_heap_free(instance, pMemory);
-        return NULL;
-    }
-    // TODO use the callback realloc function
-    if (instance && instance->alloc_callbacks.pfnAllocation) {
-        if (size <= orig_size) {
-            memset(((uint8_t *)pMemory) + size, 0, orig_size - size);
-            return pMemory;
+void loader_instance_heap_free(const struct loader_instance *instance,
+                               void *pMemory) {
+    if (pMemory != NULL) {
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+        {
+#else
+        if (instance && instance->alloc_callbacks.pfnFree) {
+            instance->alloc_callbacks.pfnFree(
+                instance->alloc_callbacks.pUserData, pMemory);
+        } else {
+#endif
+            free(pMemory);
         }
-        /* TODO: What should default alignment be? 1, 4, 8, other? */
-        void *new_ptr = instance->alloc_callbacks.pfnAllocation(
-            instance->alloc_callbacks.pUserData, size, sizeof(int),
-            alloc_scope);
-        if (!new_ptr)
-            return NULL;
-        memcpy(new_ptr, pMemory, orig_size);
-        instance->alloc_callbacks.pfnFree(instance->alloc_callbacks.pUserData,
-                                          pMemory);
-        return new_ptr;
     }
-    return realloc(pMemory, size);
 }
 
-void *loader_tls_heap_alloc(size_t size) {
-    return loader_heap_alloc(tls_instance, size,
-                             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+void *loader_instance_heap_realloc(const struct loader_instance *instance,
+                                   void *pMemory, size_t orig_size, size_t size,
+                                   VkSystemAllocationScope alloc_scope) {
+    void *pNewMem = NULL;
+    if (pMemory == NULL || orig_size == 0) {
+        pNewMem = loader_instance_heap_alloc(instance, size, alloc_scope);
+    } else if (size == 0) {
+        loader_instance_heap_free(instance, pMemory);
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+#else
+    } else if (instance && instance->alloc_callbacks.pfnReallocation) {
+        /* These are internal structures, so it's best to align everything to
+         * the largest unit size which is the size of a uint64_t.
+         */
+        pNewMem = instance->alloc_callbacks.pfnReallocation(
+            instance->alloc_callbacks.pUserData, pMemory, size,
+            sizeof(uint64_t), alloc_scope);
+#endif
+    } else {
+        pNewMem = realloc(pMemory, size);
+    }
+    return pNewMem;
 }
 
-void loader_tls_heap_free(void *pMemory) {
-    loader_heap_free(tls_instance, pMemory);
+void *loader_instance_tls_heap_alloc(size_t size) {
+    return loader_instance_heap_alloc(tls_instance, size,
+                                      VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
 }
 
+void loader_instance_tls_heap_free(void *pMemory) {
+    loader_instance_heap_free(tls_instance, pMemory);
+}
+
+void *loader_device_heap_alloc(const struct loader_device *device, size_t size,
+                               VkSystemAllocationScope alloc_scope) {
+    void *pMemory = NULL;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+    {
+#else
+    if (device && device->alloc_callbacks.pfnAllocation) {
+        /* These are internal structures, so it's best to align everything to
+         * the largest unit size which is the size of a uint64_t.
+        */
+        pMemory = device->alloc_callbacks.pfnAllocation(
+            device->alloc_callbacks.pUserData, size, sizeof(uint64_t),
+            alloc_scope);
+    } else {
+#endif
+        pMemory = malloc(size);
+    }
+    return pMemory;
+}
+
+void loader_device_heap_free(const struct loader_device *device,
+                             void *pMemory) {
+    if (pMemory != NULL) {
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+        {
+#else
+        if (device && device->alloc_callbacks.pfnFree) {
+            device->alloc_callbacks.pfnFree(device->alloc_callbacks.pUserData,
+                                            pMemory);
+        } else {
+#endif
+            free(pMemory);
+        }
+    }
+}
+
+void *loader_device_heap_realloc(const struct loader_device *device,
+                                 void *pMemory, size_t orig_size, size_t size,
+                                 VkSystemAllocationScope alloc_scope) {
+    void *pNewMem = NULL;
+    if (pMemory == NULL || orig_size == 0) {
+        pNewMem = loader_device_heap_alloc(device, size, alloc_scope);
+    } else if (size == 0) {
+        loader_device_heap_free(device, pMemory);
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+#else
+    } else if (device && device->alloc_callbacks.pfnReallocation) {
+        /* These are internal structures, so it's best to align everything to
+         * the largest unit size which is the size of a uint64_t.
+        */
+        pNewMem = device->alloc_callbacks.pfnReallocation(
+            device->alloc_callbacks.pUserData, pMemory, size, sizeof(uint64_t),
+            alloc_scope);
+#endif
+    } else {
+        pNewMem = realloc(pMemory, size);
+    }
+    return pNewMem;
+}
+
+// Environment variables
+#if defined(__linux__)
+
+static inline char *loader_getenv(const char *name,
+                                  const struct loader_instance *inst) {
+    // No allocation of memory necessary for Linux, but we should at least touch
+    // the inst pointer to get rid of compiler warnings.
+    (void)inst;
+    return getenv(name);
+}
+static inline void loader_free_getenv(const char *val,
+                                      const struct loader_instance *inst) {
+    // No freeing of memory necessary for Linux, but we should at least touch
+    // the val and inst pointers to get rid of compiler warnings.
+    (void)val;
+    (void)inst;
+}
+
+#elif defined(WIN32)
+
+static inline char *loader_getenv(const char *name,
+                                  const struct loader_instance *inst) {
+    char *retVal;
+    DWORD valSize;
+
+    valSize = GetEnvironmentVariableA(name, NULL, 0);
+
+    // valSize DOES include the null terminator, so for any set variable
+    // will always be at least 1. If it's 0, the variable wasn't set.
+    if (valSize == 0)
+        return NULL;
+
+    // Allocate the space necessary for the registry entry
+    if (NULL != inst && NULL != inst->alloc_callbacks.pfnAllocation) {
+        retVal = (char *)inst->alloc_callbacks.pfnAllocation(
+            inst->alloc_callbacks.pUserData, valSize, sizeof(char *),
+            VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+    } else {
+        retVal = (char *)malloc(valSize);
+    }
+
+    if (NULL != retVal) {
+        GetEnvironmentVariableA(name, retVal, valSize);
+    }
+
+    return retVal;
+}
+
+static inline void loader_free_getenv(char *val,
+                                      const struct loader_instance *inst) {
+    if (NULL != inst && NULL != inst->alloc_callbacks.pfnFree) {
+        inst->alloc_callbacks.pfnFree(inst->alloc_callbacks.pUserData, val);
+    } else {
+        free((void *)val);
+    }
+}
+
+#else
+
+static inline char *loader_getenv(const char *name,
+    const struct loader_instance *inst) {
+    // stub func
+    (void)inst;
+    (void)name;
+    return NULL;
+}
+static inline void loader_free_getenv(const char *val,
+    const struct loader_instance *inst) {
+    // stub func
+    (void)val;
+    (void)inst;
+}
+
+#endif
+
 void loader_log(const struct loader_instance *inst, VkFlags msg_type,
                 int32_t msg_code, const char *format, ...) {
     char msg[512];
@@ -322,21 +467,25 @@
                ERROR_SUCCESS) {
             if (value_size == sizeof(value) && value == 0) {
                 if (out == NULL) {
-                    out = loader_heap_alloc(
+                    out = loader_instance_heap_alloc(
                         inst, total_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+                    if (NULL == out) {
+                        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                                   "Out of memory can't alloc space for registry data");
+                        return NULL;
+                    }
                     out[0] = '\0';
                 } else if (strlen(out) + name_size + 1 > total_size) {
-                    out = loader_heap_realloc(
+                    out = loader_instance_heap_realloc(
                         inst, out, total_size, total_size * 2,
                         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+                    if (NULL == out) {
+                        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                                   "Out of memory can't realloc space for registry data");
+                        return NULL;
+                    }
                     total_size *= 2;
                 }
-                if (out == NULL) {
-                    loader_log(
-                        inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                        "Out of memory, failed loader_get_registry_files");
-                    return NULL;
-                }
                 if (strlen(out) == 0)
                     snprintf(out, name_size + 1, "%s", name);
                 else
@@ -502,8 +651,9 @@
                                struct loader_layer_list *layer_list) {
     if (layer_list->capacity == 0) {
         layer_list->list =
-            loader_heap_alloc(inst, sizeof(struct loader_layer_properties) * 64,
-                              VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+            loader_instance_heap_alloc(
+                inst, sizeof(struct loader_layer_properties) * 64,
+                VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
         if (layer_list->list == NULL) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                        "Out of memory can't add any layer properties to list");
@@ -517,12 +667,13 @@
     // ensure enough room to add an entry
     if ((layer_list->count + 1) * sizeof(struct loader_layer_properties) >
         layer_list->capacity) {
-        layer_list->list = loader_heap_realloc(
+        layer_list->list = loader_instance_heap_realloc(
             inst, layer_list->list, layer_list->capacity,
             layer_list->capacity * 2, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
         if (layer_list->list == NULL) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                        "realloc failed for layer list");
+            return NULL;
         }
         layer_list->capacity *= 2;
     }
@@ -547,11 +698,12 @@
                       .instance_extension_list);
         dev_ext_list = &layer_list->list[i].device_extension_list;
         if (dev_ext_list->capacity > 0 &&
+            NULL != dev_ext_list->list &&
             dev_ext_list->list->entrypoint_count > 0) {
             for (j = 0; j < dev_ext_list->list->entrypoint_count; j++) {
-                loader_heap_free(inst, dev_ext_list->list->entrypoints[j]);
+                loader_instance_heap_free(inst, dev_ext_list->list->entrypoints[j]);
             }
-            loader_heap_free(inst, dev_ext_list->list->entrypoints);
+            loader_instance_heap_free(inst, dev_ext_list->list->entrypoints);
         }
         loader_destroy_generic_list(inst,
                                     (struct loader_generic_list *)dev_ext_list);
@@ -560,7 +712,7 @@
 
     if (layer_list->capacity > 0) {
         layer_list->capacity = 0;
-        loader_heap_free(inst, layer_list->list);
+        loader_instance_heap_free(inst, layer_list->list);
     }
 }
 
@@ -703,8 +855,8 @@
                               struct loader_generic_list *list_info,
                               size_t element_size) {
     list_info->capacity = 32 * element_size;
-    list_info->list = loader_heap_alloc(inst, list_info->capacity,
-                                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    list_info->list = loader_instance_heap_alloc(
+        inst, list_info->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (list_info->list == NULL) {
         return false;
     }
@@ -715,7 +867,7 @@
 
 void loader_destroy_generic_list(const struct loader_instance *inst,
                                  struct loader_generic_list *list) {
-    loader_heap_free(inst, list->list);
+    loader_instance_heap_free(inst, list->list);
     list->count = 0;
     list->capacity = 0;
 }
@@ -754,7 +906,7 @@
         if (ext_list->count * sizeof(VkExtensionProperties) >=
             ext_list->capacity) {
 
-            ext_list->list = loader_heap_realloc(
+            ext_list->list = loader_instance_heap_realloc(
                 inst, ext_list->list, ext_list->capacity,
                 ext_list->capacity * 2, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
 
@@ -802,7 +954,7 @@
     // check for enough capacity
     if (idx * sizeof(struct loader_dev_ext_props) >= ext_list->capacity) {
 
-        ext_list->list = loader_heap_realloc(
+        ext_list->list = loader_instance_heap_realloc(
             inst, ext_list->list, ext_list->capacity, ext_list->capacity * 2,
             VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
 
@@ -817,15 +969,25 @@
            sizeof(struct loader_dev_ext_props));
     ext_list->list[idx].entrypoint_count = entry_count;
     ext_list->list[idx].entrypoints =
-        loader_heap_alloc(inst, sizeof(char *) * entry_count,
-                          VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-    if (ext_list->list[idx].entrypoints == NULL)
+        loader_instance_heap_alloc(inst, sizeof(char *) * entry_count,
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (ext_list->list[idx].entrypoints == NULL) {
+        ext_list->list[idx].entrypoint_count = 0;
         return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
     for (uint32_t i = 0; i < entry_count; i++) {
-        ext_list->list[idx].entrypoints[i] = loader_heap_alloc(
+        ext_list->list[idx].entrypoints[i] = loader_instance_heap_alloc(
             inst, strlen(entrys[i]) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-        if (ext_list->list[idx].entrypoints[i] == NULL)
+        if (ext_list->list[idx].entrypoints[i] == NULL) {
+            for (uint32_t j = 0; j < i; j++) {
+                loader_instance_heap_free(inst,
+                                          ext_list->list[idx].entrypoints[j]);
+            }
+            loader_instance_heap_free(inst, ext_list->list[idx].entrypoints);
+            ext_list->list[idx].entrypoint_count = 0;
+            ext_list->list[idx].entrypoints = NULL;
             return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
         strcpy(ext_list->list[idx].entrypoints[i], entrys[i]);
     }
     ext_list->count++;
@@ -856,7 +1018,7 @@
             continue;
         }
 
-        loader_add_to_layer_list(inst, output_list, 1, layer_prop);
+        err = loader_add_to_layer_list(inst, output_list, 1, layer_prop);
     }
 
     return err;
@@ -868,8 +1030,8 @@
 static bool loader_init_layer_list(const struct loader_instance *inst,
                                    struct loader_layer_list *list) {
     list->capacity = 32 * sizeof(struct loader_layer_properties);
-    list->list = loader_heap_alloc(inst, list->capacity,
-                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    list->list = loader_instance_heap_alloc(
+        inst, list->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (list->list == NULL) {
         return false;
     }
@@ -879,8 +1041,13 @@
 }
 
 void loader_destroy_layer_list(const struct loader_instance *inst,
+                               struct loader_device *device,
                                struct loader_layer_list *layer_list) {
-    loader_heap_free(inst, layer_list->list);
+    if (device) {
+        loader_device_heap_free(device, layer_list->list);
+    } else {
+        loader_instance_heap_free(inst, layer_list->list);
+    }
     layer_list->count = 0;
     layer_list->capacity = 0;
 }
@@ -914,10 +1081,10 @@
  * Append non-duplicate layer properties defined in prop_list
  * to the given layer_info list
  */
-void loader_add_to_layer_list(const struct loader_instance *inst,
-                              struct loader_layer_list *list,
-                              uint32_t prop_list_count,
-                              const struct loader_layer_properties *props) {
+VkResult loader_add_to_layer_list(const struct loader_instance *inst,
+                                  struct loader_layer_list *list,
+                                  uint32_t prop_list_count,
+                                  const struct loader_layer_properties *props) {
     uint32_t i;
     struct loader_layer_properties *layer;
 
@@ -926,7 +1093,7 @@
     }
 
     if (list->list == NULL)
-        return;
+        return VK_SUCCESS;
 
     for (i = 0; i < prop_list_count; i++) {
         layer = (struct loader_layer_properties *)&props[i];
@@ -941,9 +1108,15 @@
         if (list->count * sizeof(struct loader_layer_properties) >=
             list->capacity) {
 
-            list->list = loader_heap_realloc(
+            list->list = loader_instance_heap_realloc(
                 inst, list->list, list->capacity, list->capacity * 2,
                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+            if (NULL == list->list) {
+                loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                           "realloc failed for layer list when attempting to "
+                           "add new layer");
+                return VK_ERROR_OUT_OF_HOST_MEMORY;
+            }
             // double capacity
             list->capacity *= 2;
         }
@@ -952,6 +1125,8 @@
                sizeof(struct loader_layer_properties));
         list->count++;
     }
+
+    return VK_SUCCESS;
 }
 
 /**
@@ -971,8 +1146,9 @@
         if (0 == strcmp(layer_prop->info.layerName, name) &&
             (layer_prop->type & type)) {
             /* Found a layer with the same name, add to found_list */
-            loader_add_to_layer_list(inst, found_list, 1, layer_prop);
-            found = true;
+            if (VK_SUCCESS == loader_add_to_layer_list(inst, found_list, 1, layer_prop)) {
+                found = true;
+            }
         }
     }
     if (!found) {
@@ -1064,19 +1240,37 @@
     return NULL;
 }
 
-static void loader_destroy_logical_device(const struct loader_instance *inst,
-                                          struct loader_device *dev) {
-    loader_heap_free(inst, dev->app_extension_props);
-    loader_deactivate_layers(inst, &dev->activated_layer_list);
-    loader_heap_free(inst, dev);
+void loader_destroy_logical_device(const struct loader_instance *inst,
+                                   struct loader_device *dev,
+                                   const VkAllocationCallbacks *pAllocator) {
+    if (pAllocator) {
+        dev->alloc_callbacks = *pAllocator;
+    }
+    if (NULL != dev->app_extension_props) {
+        loader_device_heap_free(dev, dev->app_extension_props);
+    }
+    if (NULL != dev->activated_layer_list.list) {
+        loader_deactivate_layers(inst, dev, &dev->activated_layer_list);
+    }
+    loader_device_heap_free(dev, dev);
 }
 
 struct loader_device *
-loader_create_logical_device(const struct loader_instance *inst) {
+loader_create_logical_device(const struct loader_instance *inst,
+                             const VkAllocationCallbacks *pAllocator) {
     struct loader_device *new_dev;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+    {
+#else
+    if (pAllocator) {
+        new_dev = (struct loader_device *)pAllocator->pfnAllocation(
+            pAllocator->pUserData, sizeof(struct loader_device), sizeof(int *),
+            VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+    } else {
+#endif
+        new_dev = (struct loader_device *)malloc(sizeof(struct loader_device));
+    }
 
-    new_dev = loader_heap_alloc(inst, sizeof(struct loader_device),
-                                VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
     if (!new_dev) {
         loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "Failed to alloc struct loader-device");
@@ -1084,6 +1278,9 @@
     }
 
     memset(new_dev, 0, sizeof(struct loader_device));
+    if (pAllocator) {
+        new_dev->alloc_callbacks = *pAllocator;
+    }
 
     return new_dev;
 }
@@ -1097,7 +1294,8 @@
 
 void loader_remove_logical_device(const struct loader_instance *inst,
                                   struct loader_icd *icd,
-                                  struct loader_device *found_dev) {
+                                  struct loader_device *found_dev,
+                                  const VkAllocationCallbacks *pAllocator) {
     struct loader_device *dev, *prev_dev;
 
     if (!icd || !found_dev)
@@ -1114,27 +1312,28 @@
         prev_dev->next = found_dev->next;
     else
         icd->logical_device_list = found_dev->next;
-    loader_destroy_logical_device(inst, found_dev);
+    loader_destroy_logical_device(inst, found_dev, pAllocator);
 }
 
 static void loader_icd_destroy(struct loader_instance *ptr_inst,
-                               struct loader_icd *icd) {
+                               struct loader_icd *icd,
+                               const VkAllocationCallbacks *pAllocator) {
     ptr_inst->total_icd_count--;
     for (struct loader_device *dev = icd->logical_device_list; dev;) {
         struct loader_device *next_dev = dev->next;
-        loader_destroy_logical_device(ptr_inst, dev);
+        loader_destroy_logical_device(ptr_inst, dev, pAllocator);
         dev = next_dev;
     }
 
-    loader_heap_free(ptr_inst, icd);
+    loader_instance_heap_free(ptr_inst, icd);
 }
 
 static struct loader_icd *
 loader_icd_create(const struct loader_instance *inst) {
     struct loader_icd *icd;
 
-    icd = loader_heap_alloc(inst, sizeof(*icd),
-                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    icd = loader_instance_heap_alloc(inst, sizeof(*icd),
+                                     VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (!icd)
         return NULL;
 
@@ -1211,20 +1410,27 @@
         return;
     for (uint32_t i = 0; i < icd_libs->count; i++) {
         loader_platform_close_library(icd_libs->list[i].handle);
-        loader_heap_free(inst, icd_libs->list[i].lib_name);
+        loader_instance_heap_free(inst, icd_libs->list[i].lib_name);
     }
-    loader_heap_free(inst, icd_libs->list);
+    loader_instance_heap_free(inst, icd_libs->list);
     icd_libs->capacity = 0;
     icd_libs->count = 0;
     icd_libs->list = NULL;
 }
 
-static void loader_scanned_icd_init(const struct loader_instance *inst,
-                                    struct loader_icd_libs *icd_libs) {
+static VkResult loader_scanned_icd_init(const struct loader_instance *inst,
+                                        struct loader_icd_libs *icd_libs) {
+    VkResult err = VK_SUCCESS;
     loader_scanned_icd_clear(inst, icd_libs);
     icd_libs->capacity = 8 * sizeof(struct loader_scanned_icds);
-    icd_libs->list = loader_heap_alloc(inst, icd_libs->capacity,
-                                       VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    icd_libs->list = loader_instance_heap_alloc(
+        inst, icd_libs->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == icd_libs->list) {
+        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+            "realloc failed for layer list when attempting to add new layer");
+        err = VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    return err;
 }
 
 static void loader_scanned_icd_add(const struct loader_instance *inst,
@@ -1248,15 +1454,16 @@
     }
 
     // Get and settle on an ICD interface version
-    fp_negotiate_icd_version =
-        loader_platform_get_proc_address(handle, "vk_icdNegotiateLoaderICDInterfaceVersion");
+    fp_negotiate_icd_version = loader_platform_get_proc_address(
+        handle, "vk_icdNegotiateLoaderICDInterfaceVersion");
 
     if (!loader_get_icd_interface_version(fp_negotiate_icd_version,
-            &interface_vers)) {
-                    loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                       "ICD (%s) doesn't support interface version compatible"
-                       "with loader, skip this ICD %s", filename);
-            return;
+                                          &interface_vers)) {
+        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "ICD (%s) doesn't support interface version compatible"
+                   "with loader, skip this ICD %s",
+                   filename);
+        return;
     }
 
     fp_get_proc_addr =
@@ -1275,15 +1482,16 @@
             loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
                        "Using deprecated ICD interface of "
                        "vkGetInstanceProcAddr instead of "
-                       "vk_icdGetInstanceProcAddr for ICD %s", filename);
+                       "vk_icdGetInstanceProcAddr for ICD %s",
+                       filename);
         }
         fp_create_inst =
             loader_platform_get_proc_address(handle, "vkCreateInstance");
         if (!fp_create_inst) {
-            loader_log(
-                inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                "Couldn't get vkCreateInstance via dlsym/loadlibrary for ICD %s",
-                    filename);
+            loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                       "Couldn't get vkCreateInstance via dlsym/loadlibrary "
+                       "for ICD %s",
+                       filename);
             return;
         }
         fp_get_inst_ext_props = loader_platform_get_proc_address(
@@ -1291,7 +1499,8 @@
         if (!fp_get_inst_ext_props) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                        "Couldn't get vkEnumerateInstanceExtensionProperties "
-                       "via dlsym/loadlibrary for ICD %s", filename);
+                       "via dlsym/loadlibrary for ICD %s",
+                       filename);
             return;
         }
     } else {
@@ -1304,7 +1513,8 @@
         if (!fp_create_inst) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                        "Couldn't get vkCreateInstance via "
-                       "vk_icdGetInstanceProcAddr for ICD %s", filename);
+                       "vk_icdGetInstanceProcAddr for ICD %s",
+                       filename);
             return;
         }
         fp_get_inst_ext_props =
@@ -1313,7 +1523,8 @@
         if (!fp_get_inst_ext_props) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                        "Couldn't get vkEnumerateInstanceExtensionProperties "
-                       "via vk_icdGetInstanceProcAddr for ICD %s", filename);
+                       "via vk_icdGetInstanceProcAddr for ICD %s",
+                       filename);
             return;
         }
     }
@@ -1322,9 +1533,14 @@
     if ((icd_libs->count * sizeof(struct loader_scanned_icds)) >=
         icd_libs->capacity) {
 
-        icd_libs->list = loader_heap_realloc(
+        icd_libs->list = loader_instance_heap_realloc(
             inst, icd_libs->list, icd_libs->capacity, icd_libs->capacity * 2,
             VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+        if (NULL == icd_libs->list) {
+            loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                       "realloc failed on icd library list");
+            return;
+        }
         // double capacity
         icd_libs->capacity *= 2;
     }
@@ -1337,9 +1553,9 @@
     new_node->CreateInstance = fp_create_inst;
     new_node->interface_version = interface_vers;
 
-    new_node->lib_name = (char *)loader_heap_alloc(
+    new_node->lib_name = (char *)loader_instance_heap_alloc(
         inst, strlen(filename) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-    if (!new_node->lib_name) {
+    if (NULL == new_node->lib_name) {
         loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
                    "Out of memory can't add icd");
         return;
@@ -1408,7 +1624,7 @@
 }
 
 static void loader_debug_init(void) {
-    const char *env, *orig;
+    char *env, *orig;
 
     if (g_loader_debug > 0)
         return;
@@ -1416,9 +1632,9 @@
     g_loader_debug = 0;
 
     /* parse comma-separated debug options */
-    orig = env = loader_getenv("VK_LOADER_DEBUG");
+    orig = env = loader_getenv("VK_LOADER_DEBUG", NULL);
     while (env) {
-        const char *p = strchr(env, ',');
+        char *p = strchr(env, ',');
         size_t len;
 
         if (p)
@@ -1455,7 +1671,7 @@
         env = p + 1;
     }
 
-    loader_free_getenv(orig);
+    loader_free_getenv(orig, NULL);
 }
 
 void loader_initialize(void) {
@@ -1468,7 +1684,8 @@
 
     // initial cJSON to use alloc callbacks
     cJSON_Hooks alloc_fns = {
-        .malloc_fn = loader_tls_heap_alloc, .free_fn = loader_tls_heap_free,
+        .malloc_fn = loader_instance_tls_heap_alloc,
+        .free_fn = loader_instance_tls_heap_free,
     };
     cJSON_InitHooks(&alloc_fns);
 }
@@ -1601,23 +1818,35 @@
 /**
  * Do a deep copy of the loader_layer_properties structure.
  */
-void loader_copy_layer_properties(const struct loader_instance *inst,
-                                         struct loader_layer_properties *dst,
-                                         struct loader_layer_properties *src) {
+VkResult loader_copy_layer_properties(const struct loader_instance *inst,
+                                      struct loader_layer_properties *dst,
+                                      struct loader_layer_properties *src) {
     uint32_t cnt, i;
     memcpy(dst, src, sizeof(*src));
     dst->instance_extension_list.list =
-        loader_heap_alloc(inst, sizeof(VkExtensionProperties) *
-                                    src->instance_extension_list.count,
-                          VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+        loader_instance_heap_alloc(inst, sizeof(VkExtensionProperties) *
+                                             src->instance_extension_list.count,
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == dst->instance_extension_list.list) {
+        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "alloc failed for instance extension list");
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
     dst->instance_extension_list.capacity =
         sizeof(VkExtensionProperties) * src->instance_extension_list.count;
     memcpy(dst->instance_extension_list.list, src->instance_extension_list.list,
            dst->instance_extension_list.capacity);
     dst->device_extension_list.list =
-        loader_heap_alloc(inst, sizeof(struct loader_dev_ext_props) *
-                                    src->device_extension_list.count,
-                          VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+        loader_instance_heap_alloc(inst, sizeof(struct loader_dev_ext_props) *
+                                             src->device_extension_list.count,
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (NULL == dst->device_extension_list.list) {
+        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "alloc failed for device extension list");
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+    memset(dst->device_extension_list.list, 0, sizeof(struct loader_dev_ext_props) *
+        src->device_extension_list.count);
 
     dst->device_extension_list.capacity =
         sizeof(struct loader_dev_ext_props) * src->device_extension_list.count;
@@ -1626,17 +1855,35 @@
     if (src->device_extension_list.count > 0 &&
         src->device_extension_list.list->entrypoint_count > 0) {
         cnt = src->device_extension_list.list->entrypoint_count;
-        dst->device_extension_list.list->entrypoints = loader_heap_alloc(
-            inst, sizeof(char *) * cnt, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+        dst->device_extension_list.list->entrypoints =
+            loader_instance_heap_alloc(inst, sizeof(char *) * cnt,
+                                       VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+        if (NULL == dst->device_extension_list.list->entrypoints) {
+            loader_log(
+                inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                "alloc failed for device extension list entrypoint array");
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
+        memset(dst->device_extension_list.list->entrypoints, 0, sizeof(char *) * cnt);
+
         for (i = 0; i < cnt; i++) {
-            dst->device_extension_list.list->entrypoints[i] = loader_heap_alloc(
-                inst,
-                strlen(src->device_extension_list.list->entrypoints[i]) + 1,
-                VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+            dst->device_extension_list.list->entrypoints[i] =
+                loader_instance_heap_alloc(
+                    inst,
+                    strlen(src->device_extension_list.list->entrypoints[i]) + 1,
+                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+            if (NULL == dst->device_extension_list.list->entrypoints[i]) {
+                loader_log(
+                    inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                    "alloc failed for device extension list entrypoint %d", i);
+                return VK_ERROR_OUT_OF_HOST_MEMORY;
+            }
             strcpy(dst->device_extension_list.list->entrypoints[i],
                    src->device_extension_list.list->entrypoints[i]);
         }
     }
+
+    return VK_SUCCESS;
 }
 
 static bool
@@ -1683,9 +1930,8 @@
  * @param layer_count
  * @param ppp_layer_names
  */
-void loader_expand_layer_names(
-    struct loader_instance *inst, const char *key_name,
-    uint32_t expand_count,
+VkResult loader_expand_layer_names(
+    struct loader_instance *inst, const char *key_name, uint32_t expand_count,
     const char expand_names[][VK_MAX_EXTENSION_NAME_SIZE],
     uint32_t *layer_count, char const *const **ppp_layer_names) {
 
@@ -1694,7 +1940,7 @@
     if (!loader_find_layer_name(key_name, *layer_count,
                                 (char const **)pp_src_layers)) {
         inst->activated_layers_are_std_val = false;
-        return; // didn't find the key_name in the list.
+        return VK_SUCCESS; // didn't find the key_name in the list.
     }
 
     loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
@@ -1702,9 +1948,14 @@
                key_name);
 
     inst->activated_layers_are_std_val = true;
-    char const **pp_dst_layers = loader_heap_alloc(
+    char const **pp_dst_layers = loader_instance_heap_alloc(
         inst, (expand_count + *layer_count - 1) * sizeof(char const *),
         VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+    if (NULL == pp_dst_layers) {
+        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "alloc failed for dst layer array");
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
 
     // copy layers from src to dst, stripping key_name and anything in
     // expand_names.
@@ -1730,6 +1981,8 @@
 
     *ppp_layer_names = pp_dst_layers;
     *layer_count = dst_index;
+
+    return VK_SUCCESS;
 }
 
 void loader_delete_shadow_inst_layer_names(const struct loader_instance *inst,
@@ -1737,7 +1990,7 @@
                                            VkInstanceCreateInfo *ours) {
     /* Free the layer names array iff we had to reallocate it */
     if (orig->ppEnabledLayerNames != ours->ppEnabledLayerNames) {
-        loader_heap_free(inst, (void *)ours->ppEnabledLayerNames);
+        loader_instance_heap_free(inst, (void *)ours->ppEnabledLayerNames);
     }
 }
 
@@ -1792,16 +2045,322 @@
     struct loader_layer_properties *props;
     if (found) {
         props = loader_get_next_layer_property(inst, layer_list);
+        if (NULL == props) {
+            // Error already triggered in loader_get_next_layer_property.
+            return;
+        }
         loader_init_std_validation_props(props);
 
     }
 
 }
 
+static void loader_read_json_layer(
+    const struct loader_instance *inst,
+    struct loader_layer_list *layer_instance_list, cJSON *layer_node,
+    cJSON *item, cJSON *disable_environment, bool is_implicit, char *filename) {
+    char *temp;
+    char *name, *type, *library_path, *api_version;
+    char *implementation_version, *description;
+    cJSON *ext_item;
+    VkExtensionProperties ext_prop;
+
+/*
+ * The following are required in the "layer" object:
+ * (required) "name"
+ * (required) "type"
+ * (required) “library_path”
+ * (required) “api_version”
+ * (required) “implementation_version”
+ * (required) “description”
+ * (required for implicit layers) “disable_environment”
+ */
+
+#define GET_JSON_OBJECT(node, var)                                             \
+    {                                                                          \
+        var = cJSON_GetObjectItem(node, #var);                                 \
+        if (var == NULL) {                                                     \
+            layer_node = layer_node->next;                                     \
+            loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,               \
+                       "Didn't find required layer object %s in manifest "     \
+                       "JSON file, skipping this layer",                       \
+                       #var);                                                  \
+            return;                                                            \
+        }                                                                      \
+    }
+#define GET_JSON_ITEM(node, var)                                               \
+    {                                                                          \
+        item = cJSON_GetObjectItem(node, #var);                                \
+        if (item == NULL) {                                                    \
+            layer_node = layer_node->next;                                     \
+            loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,               \
+                       "Didn't find required layer value %s in manifest JSON " \
+                       "file, skipping this layer",                            \
+                       #var);                                                  \
+            return;                                                            \
+        }                                                                      \
+        temp = cJSON_Print(item);                                              \
+        if (temp == NULL) {                                                    \
+            layer_node = layer_node->next;                                     \
+            loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,               \
+                       "Problem accessing layer value %s in manifest JSON "    \
+                       "file, skipping this layer",                            \
+                       #var);                                                  \
+            return;                                                            \
+        }                                                                      \
+        temp[strlen(temp) - 1] = '\0';                                         \
+        var = loader_stack_alloc(strlen(temp) + 1);                            \
+        strcpy(var, &temp[1]);                                                 \
+        cJSON_Free(temp);                                                      \
+    }
+    GET_JSON_ITEM(layer_node, name)
+    GET_JSON_ITEM(layer_node, type)
+    GET_JSON_ITEM(layer_node, library_path)
+    GET_JSON_ITEM(layer_node, api_version)
+    GET_JSON_ITEM(layer_node, implementation_version)
+    GET_JSON_ITEM(layer_node, description)
+    if (is_implicit) {
+        GET_JSON_OBJECT(layer_node, disable_environment)
+    }
+#undef GET_JSON_ITEM
+#undef GET_JSON_OBJECT
+
+    // add list entry
+    struct loader_layer_properties *props = NULL;
+    if (!strcmp(type, "DEVICE")) {
+        loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                   "Device layers are deprecated skipping this layer");
+        layer_node = layer_node->next;
+        return;
+    }
+    // Allow either GLOBAL or INSTANCE type interchangeably to handle
+    // layers that must work with older loaders
+    if (!strcmp(type, "INSTANCE") || !strcmp(type, "GLOBAL")) {
+        if (layer_instance_list == NULL) {
+            layer_node = layer_node->next;
+            return;
+        }
+        props = loader_get_next_layer_property(inst, layer_instance_list);
+        if (NULL == props) {
+            // Error already triggered in loader_get_next_layer_property.
+            return;
+        }
+        props->type = (is_implicit) ? VK_LAYER_TYPE_INSTANCE_IMPLICIT
+                                    : VK_LAYER_TYPE_INSTANCE_EXPLICIT;
+    }
+
+    if (props == NULL) {
+        layer_node = layer_node->next;
+        return;
+    }
+
+    strncpy(props->info.layerName, name, sizeof(props->info.layerName));
+    props->info.layerName[sizeof(props->info.layerName) - 1] = '\0';
+
+    char *fullpath = props->lib_name;
+    char *rel_base;
+    if (loader_platform_is_path(library_path)) {
+        // a relative or absolute path
+        char *name_copy = loader_stack_alloc(strlen(filename) + 1);
+        strcpy(name_copy, filename);
+        rel_base = loader_platform_dirname(name_copy);
+        loader_expand_path(library_path, rel_base, MAX_STRING_SIZE, fullpath);
+    } else {
+        // a filename which is assumed in a system directory
+        loader_get_fullpath(library_path, DEFAULT_VK_LAYERS_PATH,
+                            MAX_STRING_SIZE, fullpath);
+    }
+    props->info.specVersion = loader_make_version(api_version);
+    props->info.implementationVersion = atoi(implementation_version);
+    strncpy((char *)props->info.description, description,
+            sizeof(props->info.description));
+    props->info.description[sizeof(props->info.description) - 1] = '\0';
+    if (is_implicit) {
+        if (!disable_environment || !disable_environment->child) {
+            loader_log(
+                inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                "Didn't find required layer child value disable_environment"
+                "in manifest JSON file, skipping this layer");
+            layer_node = layer_node->next;
+            return;
+        }
+        strncpy(props->disable_env_var.name, disable_environment->child->string,
+                sizeof(props->disable_env_var.name));
+        props->disable_env_var.name[sizeof(props->disable_env_var.name) - 1] =
+            '\0';
+        strncpy(props->disable_env_var.value,
+                disable_environment->child->valuestring,
+                sizeof(props->disable_env_var.value));
+        props->disable_env_var.value[sizeof(props->disable_env_var.value) - 1] =
+            '\0';
+    }
+
+/**
+* Now get all optional items and objects and put in list:
+* functions
+* instance_extensions
+* device_extensions
+* enable_environment (implicit layers only)
+*/
+#define GET_JSON_OBJECT(node, var)                                             \
+    { var = cJSON_GetObjectItem(node, #var); }
+#define GET_JSON_ITEM(node, var)                                               \
+    {                                                                          \
+        item = cJSON_GetObjectItem(node, #var);                                \
+        if (item != NULL) {                                                    \
+            temp = cJSON_Print(item);                                          \
+            if (temp != NULL) {                                                \
+                temp[strlen(temp) - 1] = '\0';                                 \
+                var = loader_stack_alloc(strlen(temp) + 1);                    \
+                strcpy(var, &temp[1]);                                         \
+                cJSON_Free(temp);                                              \
+            }                                                                  \
+        }                                                                      \
+    }
+
+    cJSON *instance_extensions, *device_extensions, *functions,
+        *enable_environment;
+    cJSON *entrypoints;
+    char *vkGetInstanceProcAddr, *vkGetDeviceProcAddr, *spec_version;
+    char **entry_array;
+    vkGetInstanceProcAddr = NULL;
+    vkGetDeviceProcAddr = NULL;
+    spec_version = NULL;
+    entrypoints = NULL;
+    entry_array = NULL;
+    int i, j;
+
+    /**
+    * functions
+    *     vkGetInstanceProcAddr
+    *     vkGetDeviceProcAddr
+    */
+    GET_JSON_OBJECT(layer_node, functions)
+    if (functions != NULL) {
+        GET_JSON_ITEM(functions, vkGetInstanceProcAddr)
+        GET_JSON_ITEM(functions, vkGetDeviceProcAddr)
+        if (vkGetInstanceProcAddr != NULL)
+            strncpy(props->functions.str_gipa, vkGetInstanceProcAddr,
+                    sizeof(props->functions.str_gipa));
+        props->functions.str_gipa[sizeof(props->functions.str_gipa) - 1] = '\0';
+        if (vkGetDeviceProcAddr != NULL)
+            strncpy(props->functions.str_gdpa, vkGetDeviceProcAddr,
+                    sizeof(props->functions.str_gdpa));
+        props->functions.str_gdpa[sizeof(props->functions.str_gdpa) - 1] = '\0';
+    }
+    /**
+    * instance_extensions
+    * array of
+    *     name
+    *     spec_version
+    */
+    GET_JSON_OBJECT(layer_node, instance_extensions)
+    if (instance_extensions != NULL) {
+        int count = cJSON_GetArraySize(instance_extensions);
+        for (i = 0; i < count; i++) {
+            ext_item = cJSON_GetArrayItem(instance_extensions, i);
+            GET_JSON_ITEM(ext_item, name)
+            if (name != NULL) {
+                strncpy(ext_prop.extensionName, name,
+                        sizeof(ext_prop.extensionName));
+                ext_prop.extensionName[sizeof(ext_prop.extensionName) - 1] =
+                    '\0';
+            }
+            GET_JSON_ITEM(ext_item, spec_version)
+            if (NULL != spec_version) {
+                ext_prop.specVersion = atoi(spec_version);
+            } else {
+                ext_prop.specVersion = 0;
+            }
+            bool ext_unsupported =
+                wsi_unsupported_instance_extension(&ext_prop);
+            if (!ext_unsupported) {
+                loader_add_to_ext_list(inst, &props->instance_extension_list, 1,
+                                       &ext_prop);
+            }
+        }
+    }
+    /**
+    * device_extensions
+    * array of
+    *     name
+    *     spec_version
+    *     entrypoints
+    */
+    GET_JSON_OBJECT(layer_node, device_extensions)
+    if (device_extensions != NULL) {
+        int count = cJSON_GetArraySize(device_extensions);
+        for (i = 0; i < count; i++) {
+            ext_item = cJSON_GetArrayItem(device_extensions, i);
+            GET_JSON_ITEM(ext_item, name)
+            GET_JSON_ITEM(ext_item, spec_version)
+            if (name != NULL) {
+                strncpy(ext_prop.extensionName, name,
+                        sizeof(ext_prop.extensionName));
+                ext_prop.extensionName[sizeof(ext_prop.extensionName) - 1] =
+                    '\0';
+            }
+            if (NULL != spec_version) {
+                ext_prop.specVersion = atoi(spec_version);
+            } else {
+                ext_prop.specVersion = 0;
+            }
+            // entrypoints = cJSON_GetObjectItem(ext_item, "entrypoints");
+            GET_JSON_OBJECT(ext_item, entrypoints)
+            int entry_count;
+            if (entrypoints == NULL) {
+                loader_add_to_dev_ext_list(inst, &props->device_extension_list,
+                                           &ext_prop, 0, NULL);
+                continue;
+            }
+            entry_count = cJSON_GetArraySize(entrypoints);
+            if (entry_count) {
+                entry_array =
+                    (char **)loader_stack_alloc(sizeof(char *) * entry_count);
+            }
+            for (j = 0; j < entry_count; j++) {
+                ext_item = cJSON_GetArrayItem(entrypoints, j);
+                if (ext_item != NULL) {
+                    temp = cJSON_Print(ext_item);
+                    if (NULL == temp) {
+                        entry_array[j] = NULL;
+                        continue;
+                    }
+                    temp[strlen(temp) - 1] = '\0';
+                    entry_array[j] = loader_stack_alloc(strlen(temp) + 1);
+                    strcpy(entry_array[j], &temp[1]);
+                    cJSON_Free(temp);
+                }
+            }
+            loader_add_to_dev_ext_list(inst, &props->device_extension_list,
+                                       &ext_prop, entry_count, entry_array);
+        }
+    }
+    if (is_implicit) {
+        GET_JSON_OBJECT(layer_node, enable_environment)
+
+        // enable_environment is optional
+        if (enable_environment) {
+            strncpy(props->enable_env_var.name,
+                    enable_environment->child->string,
+                    sizeof(props->enable_env_var.name));
+            props->enable_env_var.name[sizeof(props->enable_env_var.name) - 1] =
+                '\0';
+            strncpy(props->enable_env_var.value,
+                    enable_environment->child->valuestring,
+                    sizeof(props->enable_env_var.value));
+            props->enable_env_var
+                .value[sizeof(props->enable_env_var.value) - 1] = '\0';
+        }
+    }
+#undef GET_JSON_ITEM
+#undef GET_JSON_OBJECT
+}
+
 /**
  * Given a cJSON struct (json) of the top level JSON object from layer manifest
- * file, add entry to the layer_list.
- * Fill out the layer_properties in this list entry from the input cJSON object.
+ * file, add entry to the layer_list. Fill out the layer_properties in this list
+ * entry from the input cJSON object.
  *
  * \returns
  * void
@@ -1815,306 +2374,112 @@
                             cJSON *json, bool is_implicit, char *filename) {
     /* Fields in layer manifest file that are required:
      * (required) “file_format_version”
-     * following are required in the "layer" object:
-     * (required) "name"
-     * (required) "type"
-     * (required) “library_path”
-     * (required) “api_version”
-     * (required) “implementation_version”
-     * (required) “description”
-     * (required for implicit layers) “disable_environment”
+     *
+     * If more than one "layer" object are to be used, use the "layers" array
+     * instead.
      *
      * First get all required items and if any missing abort
      */
 
-    cJSON *item, *layer_node, *ext_item;
-    char *temp;
-    char *name, *type, *library_path, *api_version;
-    char *implementation_version, *description;
+    cJSON *item, *layers_node, *layer_node;
+    uint16_t file_major_vers = 0;
+    uint16_t file_minor_vers = 0;
+    uint16_t file_patch_vers = 0;
+    char *vers_tok;
     cJSON *disable_environment = NULL;
-    int i, j;
-    VkExtensionProperties ext_prop;
     item = cJSON_GetObjectItem(json, "file_format_version");
     if (item == NULL) {
         return;
     }
     char *file_vers = cJSON_PrintUnformatted(item);
-    loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
-               "Found manifest file %s, version %s", filename, file_vers);
-    if (strcmp(file_vers, "\"1.0.0\"") != 0)
-        loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
-                   "Unexpected manifest file version (expected 1.0.0), may "
-                   "cause errors");
-    loader_tls_heap_free(file_vers);
-
-    layer_node = cJSON_GetObjectItem(json, "layer");
-    if (layer_node == NULL) {
-        loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
-                   "Can't find \"layer\" object in manifest JSON file, "
-                   "skipping this file");
+    if (NULL == file_vers) {
         return;
     }
-
-    // loop through all "layer" objects in the file
-    do {
-#define GET_JSON_OBJECT(node, var)                                             \
-    {                                                                          \
-        var = cJSON_GetObjectItem(node, #var);                                 \
-        if (var == NULL) {                                                     \
-            layer_node = layer_node->next;                                     \
-            loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,               \
-                       "Didn't find required layer object %s in manifest "     \
-                       "JSON file, skipping this layer",                       \
-                       #var);                                                  \
-            continue;                                                          \
-        }                                                                      \
-    }
-#define GET_JSON_ITEM(node, var)                                               \
-    {                                                                          \
-        item = cJSON_GetObjectItem(node, #var);                                \
-        if (item == NULL) {                                                    \
-            layer_node = layer_node->next;                                     \
-            loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,               \
-                       "Didn't find required layer value %s in manifest JSON " \
-                       "file, skipping this layer",                            \
-                       #var);                                                  \
-            continue;                                                          \
-        }                                                                      \
-        temp = cJSON_Print(item);                                              \
-        temp[strlen(temp) - 1] = '\0';                                         \
-        var = loader_stack_alloc(strlen(temp) + 1);                            \
-        strcpy(var, &temp[1]);                                                 \
-        loader_tls_heap_free(temp);                                            \
-    }
-        GET_JSON_ITEM(layer_node, name)
-        GET_JSON_ITEM(layer_node, type)
-        GET_JSON_ITEM(layer_node, library_path)
-        GET_JSON_ITEM(layer_node, api_version)
-        GET_JSON_ITEM(layer_node, implementation_version)
-        GET_JSON_ITEM(layer_node, description)
-        if (is_implicit) {
-            GET_JSON_OBJECT(layer_node, disable_environment)
+    loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+               "Found manifest file %s, version %s", filename, file_vers);
+    // Get the major/minor/and patch as integers for easier comparison
+    vers_tok = strtok(file_vers, ".\"\n\r");
+    if (NULL != vers_tok) {
+        file_major_vers = (uint16_t)atoi(vers_tok);
+        vers_tok = strtok(NULL, ".\"\n\r");
+        if (NULL != vers_tok) {
+            file_minor_vers = (uint16_t)atoi(vers_tok);
+            vers_tok = strtok(NULL, ".\"\n\r");
+            if (NULL != vers_tok) {
+                file_patch_vers = (uint16_t)atoi(vers_tok);
+            }
         }
-#undef GET_JSON_ITEM
-#undef GET_JSON_OBJECT
-
-        // add list entry
-        struct loader_layer_properties *props = NULL;
-        if (!strcmp(type, "DEVICE")) {
+    }
+    if (file_major_vers != 1 || file_minor_vers != 0 || file_patch_vers > 1) {
+        loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                   "%s Unexpected manifest file version (expected 1.0.0 or "
+                   "1.0.1), may cause errors",
+                   filename);
+    }
+    cJSON_Free(file_vers);
+    // If "layers" is present, read in the array of layer objects
+    layers_node = cJSON_GetObjectItem(json, "layers");
+    if (layers_node != NULL) {
+        int numItems = cJSON_GetArraySize(layers_node);
+        if (file_major_vers == 1 && file_minor_vers == 0 &&
+            file_patch_vers == 0) {
             loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
-                    "Device layers are deprecated skipping this layer");
-                layer_node = layer_node->next;
-                continue;
-
+                       "\"layers\" tag not officially added until file version "
+                       "1.0.1, but %s is reporting version %s",
+                       filename, file_vers);
         }
-        // Allow either GLOBAL or INSTANCE type interchangeably to handle
-        // layers that must work with older loaders
-        if (!strcmp(type, "INSTANCE") || !strcmp(type, "GLOBAL")) {
-            if (layer_instance_list == NULL) {
-                layer_node = layer_node->next;
-                continue;
+        for (int curLayer = 0; curLayer < numItems; curLayer++) {
+            layer_node = cJSON_GetArrayItem(layers_node, curLayer);
+            if (layer_node == NULL) {
+                loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                           "Can't find \"layers\" array element %d object in "
+                           "manifest JSON file %s, skipping this file",
+                           curLayer, filename);
+                return;
             }
-            props = loader_get_next_layer_property(inst, layer_instance_list);
-            props->type = (is_implicit) ? VK_LAYER_TYPE_INSTANCE_IMPLICIT
-                                        : VK_LAYER_TYPE_INSTANCE_EXPLICIT;
+            loader_read_json_layer(inst, layer_instance_list, layer_node, item,
+                                   disable_environment, is_implicit, filename);
         }
-
-        if (props == NULL) {
-            layer_node = layer_node->next;
-            continue;
+    } else {
+        // Otherwise, try to read in individual layers
+        layer_node = cJSON_GetObjectItem(json, "layer");
+        if (layer_node == NULL) {
+            loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                       "Can't find \"layer\" object in manifest JSON file %s, "
+                       "skipping this file",
+                       filename);
+            return;
         }
-
-        strncpy(props->info.layerName, name, sizeof(props->info.layerName));
-        props->info.layerName[sizeof(props->info.layerName) - 1] = '\0';
-
-        char *fullpath = props->lib_name;
-        char *rel_base;
-        if (loader_platform_is_path(library_path)) {
-            // a relative or absolute path
-            char *name_copy = loader_stack_alloc(strlen(filename) + 1);
-            strcpy(name_copy, filename);
-            rel_base = loader_platform_dirname(name_copy);
-            loader_expand_path(library_path, rel_base, MAX_STRING_SIZE,
-                               fullpath);
+        // Loop through all "layer" objects in the file to get a count of them
+        // first.
+        uint16_t layer_count = 0;
+        cJSON *tempNode = layer_node;
+        do {
+            tempNode = tempNode->next;
+            layer_count++;
+        } while (tempNode != NULL);
+        /*
+         * Throw a warning if we encounter multiple "layer" objects in file
+         * versions newer than 1.0.0.  Having multiple objects with the same
+         * name at the same level is actually a JSON standard violation.
+         */
+        if (layer_count > 1 &&
+            (file_major_vers > 1 ||
+             !(file_minor_vers == 0 && file_patch_vers == 0))) {
+            loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                       "Multiple \"layer\" nodes are deprecated starting in "
+                       "file version \"1.0.1\".  Please use \"layers\" : [] "
+                       "array instead in %s.",
+                       filename);
         } else {
-            // a filename which is assumed in a system directory
-            loader_get_fullpath(library_path, DEFAULT_VK_LAYERS_PATH,
-                                MAX_STRING_SIZE, fullpath);
-        }
-        props->info.specVersion = loader_make_version(api_version);
-        props->info.implementationVersion = atoi(implementation_version);
-        strncpy((char *)props->info.description, description,
-                sizeof(props->info.description));
-        props->info.description[sizeof(props->info.description) - 1] = '\0';
-        if (is_implicit) {
-            if (!disable_environment || !disable_environment->child) {
-                loader_log(
-                    inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
-                    "Didn't find required layer child value disable_environment"
-                    "in manifest JSON file, skipping this layer");
+            do {
+                loader_read_json_layer(inst, layer_instance_list, layer_node,
+                                       item, disable_environment, is_implicit,
+                                       filename);
                 layer_node = layer_node->next;
-                continue;
-            }
-            strncpy(props->disable_env_var.name,
-                    disable_environment->child->string,
-                    sizeof(props->disable_env_var.name));
-            props->disable_env_var
-                .name[sizeof(props->disable_env_var.name) - 1] = '\0';
-            strncpy(props->disable_env_var.value,
-                    disable_environment->child->valuestring,
-                    sizeof(props->disable_env_var.value));
-            props->disable_env_var
-                .value[sizeof(props->disable_env_var.value) - 1] = '\0';
+            } while (layer_node != NULL);
         }
-
-/**
- * Now get all optional items and objects and put in list:
- * functions
- * instance_extensions
- * device_extensions
- * enable_environment (implicit layers only)
- */
-#define GET_JSON_OBJECT(node, var)                                             \
-    { var = cJSON_GetObjectItem(node, #var); }
-#define GET_JSON_ITEM(node, var)                                               \
-    {                                                                          \
-        item = cJSON_GetObjectItem(node, #var);                                \
-        if (item != NULL) {                                                    \
-            temp = cJSON_Print(item);                                          \
-            temp[strlen(temp) - 1] = '\0';                                     \
-            var = loader_stack_alloc(strlen(temp) + 1);                        \
-            strcpy(var, &temp[1]);                                             \
-            loader_tls_heap_free(temp);                                        \
-        }                                                                      \
     }
-
-        cJSON *instance_extensions, *device_extensions, *functions,
-            *enable_environment;
-        cJSON *entrypoints;
-        char *vkGetInstanceProcAddr, *vkGetDeviceProcAddr, *spec_version;
-        char **entry_array;
-        vkGetInstanceProcAddr = NULL;
-        vkGetDeviceProcAddr = NULL;
-        spec_version = NULL;
-        entrypoints = NULL;
-        entry_array = NULL;
-        /**
-         * functions
-         *     vkGetInstanceProcAddr
-         *     vkGetDeviceProcAddr
-         */
-        GET_JSON_OBJECT(layer_node, functions)
-        if (functions != NULL) {
-            GET_JSON_ITEM(functions, vkGetInstanceProcAddr)
-            GET_JSON_ITEM(functions, vkGetDeviceProcAddr)
-            if (vkGetInstanceProcAddr != NULL)
-                strncpy(props->functions.str_gipa, vkGetInstanceProcAddr,
-                        sizeof(props->functions.str_gipa));
-            props->functions.str_gipa[sizeof(props->functions.str_gipa) - 1] =
-                '\0';
-            if (vkGetDeviceProcAddr != NULL)
-                strncpy(props->functions.str_gdpa, vkGetDeviceProcAddr,
-                        sizeof(props->functions.str_gdpa));
-            props->functions.str_gdpa[sizeof(props->functions.str_gdpa) - 1] =
-                '\0';
-        }
-        /**
-         * instance_extensions
-         * array of
-         *     name
-         *     spec_version
-         */
-        GET_JSON_OBJECT(layer_node, instance_extensions)
-        if (instance_extensions != NULL) {
-            int count = cJSON_GetArraySize(instance_extensions);
-            for (i = 0; i < count; i++) {
-                ext_item = cJSON_GetArrayItem(instance_extensions, i);
-                GET_JSON_ITEM(ext_item, name)
-                GET_JSON_ITEM(ext_item, spec_version)
-                if (name != NULL) {
-                    strncpy(ext_prop.extensionName, name,
-                            sizeof(ext_prop.extensionName));
-                    ext_prop.extensionName[sizeof(ext_prop.extensionName) - 1] =
-                        '\0';
-                }
-                ext_prop.specVersion = atoi(spec_version);
-                bool ext_unsupported =
-                    wsi_unsupported_instance_extension(&ext_prop);
-                if (!ext_unsupported) {
-                    loader_add_to_ext_list(
-                        inst, &props->instance_extension_list, 1, &ext_prop);
-                }
-            }
-        }
-        /**
-         * device_extensions
-         * array of
-         *     name
-         *     spec_version
-         *     entrypoints
-         */
-        GET_JSON_OBJECT(layer_node, device_extensions)
-        if (device_extensions != NULL) {
-            int count = cJSON_GetArraySize(device_extensions);
-            for (i = 0; i < count; i++) {
-                ext_item = cJSON_GetArrayItem(device_extensions, i);
-                GET_JSON_ITEM(ext_item, name)
-                GET_JSON_ITEM(ext_item, spec_version)
-                if (name != NULL) {
-                    strncpy(ext_prop.extensionName, name,
-                            sizeof(ext_prop.extensionName));
-                    ext_prop.extensionName[sizeof(ext_prop.extensionName) - 1] =
-                        '\0';
-                }
-                ext_prop.specVersion = atoi(spec_version);
-                // entrypoints = cJSON_GetObjectItem(ext_item, "entrypoints");
-                GET_JSON_OBJECT(ext_item, entrypoints)
-                int entry_count;
-                if (entrypoints == NULL) {
-                    loader_add_to_dev_ext_list(inst,
-                                               &props->device_extension_list,
-                                               &ext_prop, 0, NULL);
-                    continue;
-                }
-                entry_count = cJSON_GetArraySize(entrypoints);
-                if (entry_count)
-                    entry_array = (char **)loader_stack_alloc(sizeof(char *) *
-                                                              entry_count);
-                for (j = 0; j < entry_count; j++) {
-                    ext_item = cJSON_GetArrayItem(entrypoints, j);
-                    if (ext_item != NULL) {
-                        temp = cJSON_Print(ext_item);
-                        temp[strlen(temp) - 1] = '\0';
-                        entry_array[j] = loader_stack_alloc(strlen(temp) + 1);
-                        strcpy(entry_array[j], &temp[1]);
-                        loader_tls_heap_free(temp);
-                    }
-                }
-                loader_add_to_dev_ext_list(inst, &props->device_extension_list,
-                                           &ext_prop, entry_count, entry_array);
-            }
-        }
-        if (is_implicit) {
-            GET_JSON_OBJECT(layer_node, enable_environment)
-
-            // enable_environment is optional
-            if (enable_environment) {
-                strncpy(props->enable_env_var.name,
-                        enable_environment->child->string,
-                        sizeof(props->enable_env_var.name));
-                props->enable_env_var
-                    .name[sizeof(props->enable_env_var.name) - 1] = '\0';
-                strncpy(props->enable_env_var.value,
-                        enable_environment->child->valuestring,
-                        sizeof(props->enable_env_var.value));
-                props->enable_env_var
-                    .value[sizeof(props->enable_env_var.value) - 1] = '\0';
-            }
-        }
-#undef GET_JSON_ITEM
-#undef GET_JSON_OBJECT
-        layer_node = layer_node->next;
-    } while (layer_node != NULL);
     return;
 }
 
@@ -2127,10 +2492,12 @@
  * location is used to look for manifest files. The location
  * is interpreted as  Registry path on Windows and a directory path(s)
  * on Linux. "home_location" is an additional directory in the users home
- * directory to look at. It is exapanded into the dir path $HOME/home_location.
- * This "home_location" is only used on Linux.
+ * directory to look at. It is expanded into the dir path
+ * $XDG_DATA_HOME/home_location or $HOME/.local/share/home_location depending
+ * on environment variables. This "home_location" is only used on Linux.
  *
  * \returns
+ * VKResult
  * A string list of manifest files to be opened in out_files param.
  * List has a pointer to string for each manifest filename.
  * When done using the list in out_files, pointers should be freed.
@@ -2143,31 +2510,32 @@
  * Linux ICD  | dirs     | files
  * Linux Layer| dirs     | dirs
  */
-static void loader_get_manifest_files(const struct loader_instance *inst,
-                                      const char *env_override,
-                                      const char *source_override, bool is_layer,
-                                      const char *location,
-                                      const char *home_location,
-                                      struct loader_manifest_files *out_files) {
-    const char *override = NULL;
-    char *loc;
+static VkResult loader_get_manifest_files(
+    const struct loader_instance *inst, const char *env_override,
+    char *source_override, bool is_layer, const char *location,
+    const char *home_location, struct loader_manifest_files *out_files) {
+    char * override = NULL;
+    char *loc, *orig_loc = NULL;
+    char *reg = NULL;
     char *file, *next_file, *name;
     size_t alloced_count = 64;
     char full_path[2048];
     DIR *sysdir = NULL;
     bool list_is_dirs = false;
     struct dirent *dent;
+    VkResult res = VK_SUCCESS;
 
     out_files->count = 0;
     out_files->filename_list = NULL;
 
     if (source_override != NULL) {
         override = source_override;
-    } else if (env_override != NULL && (override = loader_getenv(env_override))) {
+    } else if (env_override != NULL &&
+               (override = loader_getenv(env_override, inst))) {
 #if !defined(_WIN32)
         if (geteuid() != getuid() || getegid() != getgid()) {
             /* Don't allow setuid apps to use the env var: */
-            loader_free_getenv(override);
+            loader_free_getenv(override, inst);
             override = NULL;
         }
 #endif
@@ -2183,7 +2551,8 @@
             inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
             "Can't get manifest files with NULL location, env_override=%s",
             env_override);
-        return;
+        res = VK_ERROR_INITIALIZATION_FAILED;
+        goto out;
     }
 
 #if defined(_WIN32)
@@ -2198,35 +2567,45 @@
         if (loc == NULL) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                        "Out of memory can't get manifest files");
-            return;
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            goto out;
         }
         strcpy(loc, location);
 #if defined(_WIN32)
-        loc = loader_get_registry_files(inst, loc);
-        if (loc == NULL) {
+        reg = loader_get_registry_files(inst, loc);
+        if (reg == NULL) {
             if (!is_layer) {
                 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                            "Registry lookup failed can't get ICD manifest "
                            "files, do you have a Vulkan driver installed");
+                // This typically only fails when out of memory, which is
+                // critical
+                // if this is for the loader.
+                res = VK_ERROR_OUT_OF_HOST_MEMORY;
             } else {
                 // warning only for layers
                 loader_log(
                     inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
                     "Registry lookup failed can't get layer manifest files");
+                // Return success for now since it's not critical for layers
+                res = VK_SUCCESS;
             }
-            return;
+            goto out;
         }
+        orig_loc = loc;
+        loc = reg;
 #endif
     } else {
         loc = loader_stack_alloc(strlen(override) + 1);
         if (loc == NULL) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                        "Out of memory can't get manifest files");
-            return;
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            goto out;
         }
         strcpy(loc, override);
         if (source_override == NULL) {
-            loader_free_getenv(override);
+            loader_free_getenv(override, inst);
         }
     }
 
@@ -2259,7 +2638,7 @@
             if (dir == NULL) {
                 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                            "Out of memory can't get manifest files");
-                return;
+                goto out;
             }
             strcpy(dir, loc);
 
@@ -2274,28 +2653,32 @@
             const char *suf = name + nlen - 5;
             if ((nlen > 5) && !strncmp(suf, ".json", 5)) {
                 if (out_files->count == 0) {
-                    out_files->filename_list =
-                        loader_heap_alloc(inst, alloced_count * sizeof(char *),
-                                          VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+                    out_files->filename_list = loader_instance_heap_alloc(
+                        inst, alloced_count * sizeof(char *),
+                        VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
                 } else if (out_files->count == alloced_count) {
-                    out_files->filename_list =
-                        loader_heap_realloc(inst, out_files->filename_list,
-                                            alloced_count * sizeof(char *),
-                                            alloced_count * sizeof(char *) * 2,
-                                            VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+                    out_files->filename_list = loader_instance_heap_realloc(
+                        inst, out_files->filename_list,
+                        alloced_count * sizeof(char *),
+                        alloced_count * sizeof(char *) * 2,
+                        VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
                     alloced_count *= 2;
                 }
                 if (out_files->filename_list == NULL) {
                     loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                                "Out of memory can't alloc manifest file list");
-                    return;
+                    res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                    goto out;
                 }
-                out_files->filename_list[out_files->count] = loader_heap_alloc(
-                    inst, strlen(name) + 1, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+                out_files->filename_list[out_files->count] =
+                    loader_instance_heap_alloc(
+                        inst, strlen(name) + 1,
+                        VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
                 if (out_files->filename_list[out_files->count] == NULL) {
                     loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                                "Out of memory can't get manifest files");
-                    return;
+                    res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                    goto out;
                 }
                 strcpy(out_files->filename_list[out_files->count], name);
                 out_files->count++;
@@ -2307,8 +2690,9 @@
             }
             if (list_is_dirs) {
                 dent = readdir(sysdir);
-                if (dent == NULL)
+                if (dent == NULL) {
                     break;
+                }
                 name = &(dent->d_name[0]);
                 loader_get_fullpath(name, file, sizeof(full_path), full_path);
                 name = full_path;
@@ -2316,23 +2700,27 @@
                 break;
             }
         }
-        if (sysdir)
+        if (sysdir) {
             closedir(sysdir);
+            sysdir = NULL;
+        }
         file = next_file;
 #if !defined(_WIN32)
         if (home_location != NULL &&
             (next_file == NULL || *next_file == '\0') && override == NULL) {
-            char *home = secure_getenv("HOME");
-            if (home != NULL) {
-                size_t len;
-                char *home_loc = loader_stack_alloc(strlen(home) + 2 +
+            char *xdgdatahome = secure_getenv("XDG_DATA_HOME");
+            size_t len;
+            if (xdgdatahome != NULL) {
+
+                char *home_loc = loader_stack_alloc(strlen(xdgdatahome) + 2 +
                                                     strlen(home_location));
                 if (home_loc == NULL) {
                     loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                                "Out of memory can't get manifest files");
-                    return;
+                    res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                    goto out;
                 }
-                strcpy(home_loc, home);
+                strcpy(home_loc, xdgdatahome);
                 // Add directory separator if needed
                 if (home_location[0] != DIRECTORY_SYMBOL) {
                     len = strlen(home_loc);
@@ -2346,14 +2734,72 @@
 
                 loader_log(
                     inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
-                    "Searching the following paths for manifest files: %s\n",
+                    "Searching the following path for manifest files: %s\n",
                     home_loc);
                 list_is_dirs = true;
+
+            } else {
+
+                char *home = secure_getenv("HOME");
+                if (home != NULL) {
+                    char *home_loc = loader_stack_alloc(strlen(home) + 16 +
+                                                        strlen(home_location));
+                    if (home_loc == NULL) {
+                        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                                "Out of memory can't get manifest files");
+                        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                        goto out;
+                    }
+                    strcpy(home_loc, home);
+
+                    len = strlen(home);
+                    if (home[len] != DIRECTORY_SYMBOL) {
+                        home_loc[len] = DIRECTORY_SYMBOL;
+                        home_loc[len + 1] = '\0';
+                    }
+                    strcat(home_loc, ".local/share");
+
+                    if (home_location[0] != DIRECTORY_SYMBOL) {
+                        len = strlen(home_loc);
+                        home_loc[len] = DIRECTORY_SYMBOL;
+                        home_loc[len + 1] = '\0';
+                    }
+                    strcat(home_loc, home_location);
+                    file = home_loc;
+                    next_file = loader_get_next_path(file);
+                    home_location = NULL;
+
+                    loader_log(
+                        inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+                        "Searching the following path for manifest files: %s\n",
+                        home_loc);
+                    list_is_dirs = true;
+                } else {
+                    // without knowing HOME, we just.. give up
+                }
             }
         }
 #endif
     }
-    return;
+
+out:
+    if (VK_SUCCESS != res && NULL != out_files->filename_list) {
+        for (uint32_t remove = 0; remove < out_files->count; remove++) {
+            loader_instance_heap_free(inst, out_files->filename_list[remove]);
+        }
+        loader_instance_heap_free(inst, out_files->filename_list);
+        out_files->count = 0;
+        out_files->filename_list = NULL;
+    }
+
+    if (NULL != sysdir) {
+        closedir(sysdir);
+    }
+
+    if (NULL != reg && reg != orig_loc) {
+        loader_instance_heap_free(inst, reg);
+    }
+    return res;
 }
 
 void loader_init_icd_lib_list() {}
@@ -2368,44 +2814,81 @@
  * manifest files it finds the ICD libraries.
  *
  * \returns
- * a list of icds that were discovered
+ * Vulkan result
+ * (on result == VK_SUCCESS) a list of icds that were discovered
  */
-void loader_icd_scan(const struct loader_instance *inst,
-                     struct loader_icd_libs *icds) {
+VkResult loader_icd_scan(const struct loader_instance *inst,
+                         struct loader_icd_libs *icds) {
     char *file_str;
+    uint16_t file_major_vers = 0;
+    uint16_t file_minor_vers = 0;
+    uint16_t file_patch_vers = 0;
+    char *vers_tok;
     struct loader_manifest_files manifest_files;
+    VkResult res = VK_SUCCESS;
+    bool lockedMutex = false;
+    cJSON *json = NULL;
 
-    loader_scanned_icd_init(inst, icds);
+    memset(&manifest_files, 0, sizeof(struct loader_manifest_files));
+
+    res = loader_scanned_icd_init(inst, icds);
+    if (VK_SUCCESS != res) {
+        goto out;
+    }
+
     // Get a list of manifest files for ICDs
-    loader_get_manifest_files(inst, "VK_ICD_FILENAMES", NULL, false,
-                              DEFAULT_VK_DRIVERS_INFO, HOME_VK_DRIVERS_INFO,
-                              &manifest_files);
-    if (manifest_files.count == 0)
-        return;
+    res = loader_get_manifest_files(inst, "VK_ICD_FILENAMES", NULL, false,
+                                    DEFAULT_VK_DRIVERS_INFO,
+                                    HOME_VK_DRIVERS_INFO, &manifest_files);
+    if (VK_SUCCESS != res || manifest_files.count == 0) {
+        goto out;
+    }
     loader_platform_thread_lock_mutex(&loader_json_lock);
+    lockedMutex = true;
     for (uint32_t i = 0; i < manifest_files.count; i++) {
         file_str = manifest_files.filename_list[i];
-        if (file_str == NULL)
+        if (file_str == NULL) {
             continue;
+        }
 
-        cJSON *json;
         json = loader_get_json(inst, file_str);
-        if (!json)
+        if (!json) {
             continue;
+        }
         cJSON *item, *itemICD;
         item = cJSON_GetObjectItem(json, "file_format_version");
         if (item == NULL) {
-            loader_platform_thread_unlock_mutex(&loader_json_lock);
-            return;
+            res = VK_ERROR_INITIALIZATION_FAILED;
+            goto out;
         }
         char *file_vers = cJSON_Print(item);
+        if (NULL == file_vers) {
+            // Only reason the print can fail is if there was an allocation
+            // issue
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            goto out;
+        }
         loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
                    "Found manifest file %s, version %s", file_str, file_vers);
-        if (strcmp(file_vers, "\"1.0.0\"") != 0)
+        // Get the major/minor/and patch as integers for easier comparison
+        vers_tok = strtok(file_vers, ".\"\n\r");
+        if (NULL != vers_tok) {
+            file_major_vers = (uint16_t)atoi(vers_tok);
+            vers_tok = strtok(NULL, ".\"\n\r");
+            if (NULL != vers_tok) {
+                file_minor_vers = (uint16_t)atoi(vers_tok);
+                vers_tok = strtok(NULL, ".\"\n\r");
+                if (NULL != vers_tok) {
+                    file_patch_vers = (uint16_t)atoi(vers_tok);
+                }
+            }
+        }
+        if (file_major_vers != 1 || file_minor_vers != 0 || file_patch_vers > 1)
             loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
-                       "Unexpected manifest file version (expected 1.0.0), may "
+                       "Unexpected manifest file version (expected 1.0.0 or "
+                       "1.0.1), may "
                        "cause errors");
-        loader_tls_heap_free(file_vers);
+        cJSON_Free(file_vers);
         itemICD = cJSON_GetObjectItem(json, "ICD");
         if (itemICD != NULL) {
             item = cJSON_GetObjectItem(itemICD, "library_path");
@@ -2416,23 +2899,23 @@
                                "Can't find \"library_path\" in ICD JSON file "
                                "%s, skipping",
                                file_str);
-                    loader_tls_heap_free(temp);
-                    loader_heap_free(inst, file_str);
+                    cJSON_Free(temp);
                     cJSON_Delete(json);
+                    json = NULL;
                     continue;
                 }
                 // strip out extra quotes
                 temp[strlen(temp) - 1] = '\0';
                 char *library_path = loader_stack_alloc(strlen(temp) + 1);
                 strcpy(library_path, &temp[1]);
-                loader_tls_heap_free(temp);
+                cJSON_Free(temp);
                 if (!library_path || strlen(library_path) == 0) {
                     loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
                                "Can't find \"library_path\" in ICD JSON file "
                                "%s, skipping",
                                file_str);
-                    loader_heap_free(inst, file_str);
                     cJSON_Delete(json);
+                    json = NULL;
                     continue;
                 }
                 char fullpath[MAX_STRING_SIZE];
@@ -2459,26 +2942,50 @@
                 item = cJSON_GetObjectItem(itemICD, "api_version");
                 if (item != NULL) {
                     temp = cJSON_Print(item);
+                    if (NULL == temp) {
+                        // Only reason the print can fail is if there was an
+                        // allocation issue
+                        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+                        goto out;
+                    }
                     vers = loader_make_version(temp);
-                    loader_tls_heap_free(temp);
+                    cJSON_Free(temp);
                 }
                 loader_scanned_icd_add(inst, icds, fullpath, vers);
-            } else
+            } else {
                 loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
                            "Can't find \"library_path\" object in ICD JSON "
                            "file %s, skipping",
                            file_str);
-        } else
+            }
+        } else {
             loader_log(
                 inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
                 "Can't find \"ICD\" object in ICD JSON file %s, skipping",
                 file_str);
+        }
 
-        loader_heap_free(inst, file_str);
+        cJSON_Delete(json);
+        json = NULL;
+    }
+
+out:
+    if (NULL != json) {
         cJSON_Delete(json);
     }
-    loader_heap_free(inst, manifest_files.filename_list);
-    loader_platform_thread_unlock_mutex(&loader_json_lock);
+    if (NULL != manifest_files.filename_list) {
+        for (uint32_t i = 0; i < manifest_files.count; i++) {
+            if (NULL != manifest_files.filename_list[i]) {
+                loader_instance_heap_free(inst,
+                                          manifest_files.filename_list[i]);
+            }
+        }
+        loader_instance_heap_free(inst, manifest_files.filename_list);
+    }
+    if (lockedMutex) {
+        loader_platform_thread_unlock_mutex(&loader_json_lock);
+    }
+    return res;
 }
 
 void loader_layer_scan(const struct loader_instance *inst,
@@ -2487,26 +2994,40 @@
     struct loader_manifest_files
         manifest_files[2]; // [0] = explicit, [1] = implicit
     cJSON *json;
-    uint32_t i;
     uint32_t implicit;
+    bool lockedMutex = false;
 
-    // Get a list of manifest files for  explicit layers
-    loader_get_manifest_files(inst, LAYERS_PATH_ENV, LAYERS_SOURCE_PATH, true,
-                              DEFAULT_VK_ELAYERS_INFO, HOME_VK_ELAYERS_INFO,
-                              &manifest_files[0]);
+    memset(manifest_files, 0, sizeof(struct loader_manifest_files) * 2);
+
+    // Get a list of manifest files for explicit layers
+    if (VK_SUCCESS !=
+        loader_get_manifest_files(inst, LAYERS_PATH_ENV, LAYERS_SOURCE_PATH,
+                                  true, DEFAULT_VK_ELAYERS_INFO,
+                                  HOME_VK_ELAYERS_INFO, &manifest_files[0])) {
+        goto out;
+    }
+
+    // Get a list of manifest files for any implicit layers
     // Pass NULL for environment variable override - implicit layers are not
     // overridden by LAYERS_PATH_ENV
-    loader_get_manifest_files(inst, NULL, NULL, true, DEFAULT_VK_ILAYERS_INFO,
-                              HOME_VK_ILAYERS_INFO, &manifest_files[1]);
-    if (manifest_files[0].count == 0 && manifest_files[1].count == 0)
-        return;
+    if (VK_SUCCESS != loader_get_manifest_files(
+                          inst, NULL, NULL, true, DEFAULT_VK_ILAYERS_INFO,
+                          HOME_VK_ILAYERS_INFO, &manifest_files[1])) {
+        goto out;
+    }
 
-    /* cleanup any previously scanned libraries */
+    // Make sure we have at least one layer, if not, go ahead and return
+    if (manifest_files[0].count == 0 && manifest_files[1].count == 0) {
+        goto out;
+    }
+
+    // cleanup any previously scanned libraries
     loader_delete_layer_properties(inst, instance_layers);
 
     loader_platform_thread_lock_mutex(&loader_json_lock);
+    lockedMutex = true;
     for (implicit = 0; implicit < 2; implicit++) {
-        for (i = 0; i < manifest_files[implicit].count; i++) {
+        for (uint32_t i = 0; i < manifest_files[implicit].count; i++) {
             file_str = manifest_files[implicit].filename_list[i];
             if (file_str == NULL)
                 continue;
@@ -2519,23 +3040,32 @@
 
             loader_add_layer_properties(inst, instance_layers, json,
                                         (implicit == 1), file_str);
-
-            loader_heap_free(inst, file_str);
             cJSON_Delete(json);
         }
     }
-    if (manifest_files[0].count != 0)
-        loader_heap_free(inst, manifest_files[0].filename_list);
-
-    if (manifest_files[1].count != 0)
-        loader_heap_free(inst, manifest_files[1].filename_list);
 
     // add a meta layer for validation if the validation layers are all present
-    loader_add_layer_property_meta(
-        inst, sizeof(std_validation_names) / sizeof(std_validation_names[0]),
-        std_validation_names, instance_layers);
+    loader_add_layer_property_meta(inst, sizeof(std_validation_names) /
+                                             sizeof(std_validation_names[0]),
+                                   std_validation_names, instance_layers);
 
-    loader_platform_thread_unlock_mutex(&loader_json_lock);
+out:
+
+    for (uint32_t manFile = 0; manFile < 2; manFile++) {
+        if (NULL != manifest_files[manFile].filename_list) {
+            for (uint32_t i = 0; i < manifest_files[manFile].count; i++) {
+                if (NULL != manifest_files[manFile].filename_list[i]) {
+                    loader_instance_heap_free(
+                        inst, manifest_files[manFile].filename_list[i]);
+                }
+            }
+            loader_instance_heap_free(inst,
+                                      manifest_files[manFile].filename_list);
+        }
+    }
+    if (lockedMutex) {
+        loader_platform_thread_unlock_mutex(&loader_json_lock);
+    }
 }
 
 void loader_implicit_layer_scan(const struct loader_instance *inst,
@@ -2547,9 +3077,10 @@
 
     // Pass NULL for environment variable override - implicit layers are not
     // overridden by LAYERS_PATH_ENV
-    loader_get_manifest_files(inst, NULL, NULL, true, DEFAULT_VK_ILAYERS_INFO,
-                              HOME_VK_ILAYERS_INFO, &manifest_files);
-    if (manifest_files.count == 0) {
+    VkResult res = loader_get_manifest_files(
+        inst, NULL, NULL, true, DEFAULT_VK_ILAYERS_INFO, HOME_VK_ILAYERS_INFO,
+        &manifest_files);
+    if (VK_SUCCESS != res || manifest_files.count == 0) {
         return;
     }
 
@@ -2570,21 +3101,18 @@
             continue;
         }
 
-        loader_add_layer_properties(inst, instance_layers, json,
-                                    true, file_str);
+        loader_add_layer_properties(inst, instance_layers, json, true,
+                                    file_str);
 
-        loader_heap_free(inst, file_str);
+        loader_instance_heap_free(inst, file_str);
         cJSON_Delete(json);
     }
-
-    if (manifest_files.count != 0) {
-        loader_heap_free(inst, manifest_files.filename_list);
-    }
+    loader_instance_heap_free(inst, manifest_files.filename_list);
 
     // add a meta layer for validation if the validation layers are all present
-    loader_add_layer_property_meta(
-        inst, sizeof(std_validation_names) / sizeof(std_validation_names[0]),
-        std_validation_names, instance_layers);
+    loader_add_layer_property_meta(inst, sizeof(std_validation_names) /
+                                             sizeof(std_validation_names[0]),
+                                   std_validation_names, instance_layers);
 
     loader_platform_thread_unlock_mutex(&loader_json_lock);
 }
@@ -2733,8 +3261,8 @@
 
 static void loader_free_dev_ext_table(struct loader_instance *inst) {
     for (uint32_t i = 0; i < MAX_NUM_DEV_EXTS; i++) {
-        loader_heap_free(inst, inst->disp_hash[i].func_name);
-        loader_heap_free(inst, inst->disp_hash[i].list.index);
+        loader_instance_heap_free(inst, inst->disp_hash[i].func_name);
+        loader_instance_heap_free(inst, inst->disp_hash[i].list.index);
     }
     memset(inst->disp_hash, 0, sizeof(inst->disp_hash));
 }
@@ -2748,7 +3276,7 @@
     if (!inst->disp_hash[idx].func_name) {
         // no entry here at this idx, so use it
         assert(list->capacity == 0);
-        inst->disp_hash[idx].func_name = (char *)loader_heap_alloc(
+        inst->disp_hash[idx].func_name = (char *)loader_instance_heap_alloc(
             inst, strlen(funcName) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
         if (inst->disp_hash[idx].func_name == NULL) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -2762,7 +3290,7 @@
 
     // check for enough capacity
     if (list->capacity == 0) {
-        list->index = loader_heap_alloc(inst, 8 * sizeof(*(list->index)),
+        list->index = loader_instance_heap_alloc(inst, 8 * sizeof(*(list->index)),
                                         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
         if (list->index == NULL) {
             loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -2771,7 +3299,7 @@
         }
         list->capacity = 8 * sizeof(*(list->index));
     } else if (list->capacity < (list->count + 1) * sizeof(*(list->index))) {
-        list->index = loader_heap_realloc(inst, list->index, list->capacity,
+        list->index = loader_instance_heap_realloc(inst, list->index, list->capacity,
                                           list->capacity * 2,
                                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
         if (list->index == NULL) {
@@ -2789,7 +3317,7 @@
         if (!inst->disp_hash[i].func_name) {
             assert(inst->disp_hash[i].list.capacity == 0);
             inst->disp_hash[i].func_name =
-                (char *)loader_heap_alloc(inst, strlen(funcName) + 1,
+                (char *)loader_instance_heap_alloc(inst, strlen(funcName) + 1,
                                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
             if (inst->disp_hash[i].func_name == NULL) {
                 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -2926,6 +3454,7 @@
 }
 
 void loader_deactivate_layers(const struct loader_instance *instance,
+                              struct loader_device *device,
                               struct loader_layer_list *list) {
     /* delete instance list of enabled layers and close any layer libraries */
     for (uint32_t i = 0; i < list->count; i++) {
@@ -2933,7 +3462,7 @@
 
         loader_close_layer_lib(instance, layer_prop);
     }
-    loader_destroy_layer_list(instance, list);
+    loader_destroy_layer_list(instance, device, list);
 }
 
 /**
@@ -2960,23 +3489,25 @@
             if (prop->enable_env_var.name[0] == 0) {
                 enable = true;
             } else {
-                env_value = loader_getenv(prop->enable_env_var.name);
+                env_value = loader_getenv(prop->enable_env_var.name, inst);
                 if (env_value && !strcmp(prop->enable_env_var.value, env_value))
                     enable = true;
-                loader_free_getenv(env_value);
+                loader_free_getenv(env_value, inst);
             }
 
             // disable_environment has priority, i.e. if both enable and disable
             // environment variables are set, the layer is disabled. Implicit
             // layers
             // are required to have a disable_environment variables
-            env_value = loader_getenv(prop->disable_env_var.name);
-            if (env_value)
+            env_value = loader_getenv(prop->disable_env_var.name, inst);
+            if (env_value) {
                 enable = false;
-            loader_free_getenv(env_value);
+            }
+            loader_free_getenv(env_value, inst);
 
-            if (enable)
+            if (enable) {
                 loader_add_to_layer_list(inst, list, 1, prop);
+            }
         }
     }
 }
@@ -2994,7 +3525,7 @@
     char *layerEnv;
     char *next, *name;
 
-    layerEnv = loader_getenv(env_name);
+    layerEnv = loader_getenv(env_name, inst);
     if (layerEnv == NULL) {
         return;
     }
@@ -3004,7 +3535,7 @@
     }
     strcpy(name, layerEnv);
 
-    loader_free_getenv(layerEnv);
+    loader_free_getenv(layerEnv, inst);
 
     while (name && *name) {
         next = loader_get_next_path(name);
@@ -3460,10 +3991,9 @@
  * Terminator functions for the Instance chain
  * All named terminator_<Vulakn API name>
  */
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
-                          const VkAllocationCallbacks *pAllocator,
-                          VkInstance *pInstance) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(
+    const VkInstanceCreateInfo *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
     struct loader_icd *icd;
     VkExtensionProperties *prop;
     char **filtered_extension_names = NULL;
@@ -3494,51 +4024,58 @@
 
     for (uint32_t i = 0; i < ptr_instance->icd_libs.count; i++) {
         icd = loader_icd_add(ptr_instance, &ptr_instance->icd_libs.list[i]);
-        if (icd) {
-            icd_create_info.enabledExtensionCount = 0;
-            struct loader_extension_list icd_exts;
-
-            loader_log(ptr_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
-                       "Build ICD instance extension list");
-            // traverse scanned icd list adding non-duplicate extensions to the
-            // list
-            loader_init_generic_list(ptr_instance,
-                                     (struct loader_generic_list *)&icd_exts,
-                                     sizeof(VkExtensionProperties));
-            loader_add_instance_extensions(
-                ptr_instance,
-                icd->this_icd_lib->EnumerateInstanceExtensionProperties,
-                icd->this_icd_lib->lib_name, &icd_exts);
-
-            for (uint32_t j = 0; j < pCreateInfo->enabledExtensionCount; j++) {
-                prop = get_extension_property(
-                    pCreateInfo->ppEnabledExtensionNames[j], &icd_exts);
-                if (prop) {
-                    filtered_extension_names[icd_create_info
-                                                 .enabledExtensionCount] =
-                        (char *)pCreateInfo->ppEnabledExtensionNames[j];
-                    icd_create_info.enabledExtensionCount++;
-                }
+        if (NULL == icd) {
+            while (NULL != ptr_instance->icds) {
+                icd = ptr_instance->icds;
+                ptr_instance->icds = icd->next;
+                icd->DestroyInstance(icd->instance, pAllocator);
+                loader_icd_destroy(ptr_instance, icd, pAllocator);
             }
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
+        icd_create_info.enabledExtensionCount = 0;
+        struct loader_extension_list icd_exts;
 
-            loader_destroy_generic_list(
-                ptr_instance, (struct loader_generic_list *)&icd_exts);
+        loader_log(ptr_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+                   "Build ICD instance extension list");
+        // traverse scanned icd list adding non-duplicate extensions to the
+        // list
+        loader_init_generic_list(ptr_instance,
+                                 (struct loader_generic_list *)&icd_exts,
+                                 sizeof(VkExtensionProperties));
+        loader_add_instance_extensions(
+            ptr_instance,
+            icd->this_icd_lib->EnumerateInstanceExtensionProperties,
+            icd->this_icd_lib->lib_name, &icd_exts);
 
-            res = ptr_instance->icd_libs.list[i].CreateInstance(
-                &icd_create_info, pAllocator, &(icd->instance));
-            if (res == VK_SUCCESS)
-                success = loader_icd_init_entrys(
-                    icd, icd->instance,
-                    ptr_instance->icd_libs.list[i].GetInstanceProcAddr);
-
-            if (res != VK_SUCCESS || !success) {
-                ptr_instance->icds = ptr_instance->icds->next;
-                loader_icd_destroy(ptr_instance, icd);
-                loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                           "ICD ignored: failed to CreateInstance and find "
-                           "entrypoints with ICD");
+        for (uint32_t j = 0; j < pCreateInfo->enabledExtensionCount; j++) {
+            prop = get_extension_property(
+                pCreateInfo->ppEnabledExtensionNames[j], &icd_exts);
+            if (prop) {
+                filtered_extension_names[icd_create_info
+                                             .enabledExtensionCount] =
+                    (char *)pCreateInfo->ppEnabledExtensionNames[j];
+                icd_create_info.enabledExtensionCount++;
             }
         }
+
+        loader_destroy_generic_list(ptr_instance,
+                                    (struct loader_generic_list *)&icd_exts);
+
+        res = ptr_instance->icd_libs.list[i].CreateInstance(
+            &icd_create_info, pAllocator, &(icd->instance));
+        if (res == VK_SUCCESS)
+            success = loader_icd_init_entrys(
+                icd, icd->instance,
+                ptr_instance->icd_libs.list[i].GetInstanceProcAddr);
+
+        if (res != VK_SUCCESS || !success) {
+            ptr_instance->icds = ptr_instance->icds->next;
+            loader_icd_destroy(ptr_instance, icd, pAllocator);
+            loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                       "ICD ignored: failed to CreateInstance and find "
+                       "entrypoints with ICD");
+        }
     }
 
     /*
@@ -3557,9 +4094,8 @@
     return VK_SUCCESS;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-terminator_DestroyInstance(VkInstance instance,
-                           const VkAllocationCallbacks *pAllocator) {
+VKAPI_ATTR void VKAPI_CALL terminator_DestroyInstance(
+    VkInstance instance, const VkAllocationCallbacks *pAllocator) {
     struct loader_instance *ptr_instance = loader_instance(instance);
     struct loader_icd *icds = ptr_instance->icds;
     struct loader_icd *next_icd;
@@ -3586,7 +4122,7 @@
         }
         next_icd = icds->next;
         icds->instance = VK_NULL_HANDLE;
-        loader_icd_destroy(ptr_instance, icds);
+        loader_icd_destroy(ptr_instance, icds, pAllocator);
 
         icds = next_icd;
     }
@@ -3597,23 +4133,26 @@
     loader_destroy_generic_list(
         ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list);
     if (ptr_instance->phys_devs_term)
-        loader_heap_free(ptr_instance, ptr_instance->phys_devs_term);
+        loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs_term);
     loader_free_dev_ext_table(ptr_instance);
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_CreateDevice(VkPhysicalDevice physicalDevice,
-                        const VkDeviceCreateInfo *pCreateInfo,
-                        const VkAllocationCallbacks *pAllocator,
-                        VkDevice *pDevice) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice(
+    VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
+    VkResult res = VK_SUCCESS;
     struct loader_physical_device *phys_dev;
     phys_dev = (struct loader_physical_device *)physicalDevice;
 
     struct loader_device *dev = (struct loader_device *)*pDevice;
     PFN_vkCreateDevice fpCreateDevice = phys_dev->this_icd->CreateDevice;
+    struct loader_extension_list icd_exts;
+
+    icd_exts.list = NULL;
 
     if (fpCreateDevice == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
+        res = VK_ERROR_INITIALIZATION_FAILED;
+        goto out;
     }
 
     VkDeviceCreateInfo localCreateInfo;
@@ -3641,12 +4180,11 @@
         (const char *const *)filtered_extension_names;
 
     /* Get the physical device (ICD) extensions  */
-    struct loader_extension_list icd_exts;
-    VkResult res;
     if (!loader_init_generic_list(phys_dev->this_icd->this_instance,
                                   (struct loader_generic_list *)&icd_exts,
                                   sizeof(VkExtensionProperties))) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
     res = loader_add_device_extensions(
@@ -3655,7 +4193,7 @@
         phys_dev->phys_dev, phys_dev->this_icd->this_icd_lib->lib_name,
         &icd_exts);
     if (res != VK_SUCCESS) {
-        return res;
+        goto out;
     }
 
     for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
@@ -3677,7 +4215,7 @@
                                            pAllocator, &dev->device);
 
     if (res != VK_SUCCESS) {
-        return res;
+        goto out;
     }
 
     *pDevice = dev->device;
@@ -3687,6 +4225,12 @@
     /* Init dispatch pointer in new device object */
     loader_init_dispatch(*pDevice, &dev->loader_dispatch);
 
+out:
+    if (NULL != icd_exts.list) {
+        loader_destroy_generic_list(phys_dev->this_icd->this_instance,
+                                    (struct loader_generic_list *)&icd_exts);
+    }
+
     return res;
 }
 
@@ -3752,8 +4296,8 @@
                      : *pPhysicalDeviceCount;
 
     if (inst->phys_devs_term)
-        loader_heap_free(inst, inst->phys_devs_term);
-    inst->phys_devs_term = loader_heap_alloc(
+        loader_instance_heap_free(inst, inst->phys_devs_term);
+    inst->phys_devs_term = loader_instance_heap_alloc(
         inst, sizeof(struct loader_physical_device) * copy_count,
         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (!inst->phys_devs_term)
@@ -3923,8 +4467,6 @@
         loader_add_to_ext_list(icd->this_instance, &all_exts, icd_exts.count,
                                icd_exts.list);
 
-        loader_init_layer_list(icd->this_instance, &implicit_layer_list);
-
         loader_add_layer_implicit(
             icd->this_instance, VK_LAYER_TYPE_INSTANCE_IMPLICIT,
             &implicit_layer_list, &icd->this_instance->instance_layer_list);
@@ -3954,6 +4496,8 @@
         }
         loader_destroy_generic_list(icd->this_instance,
                                     (struct loader_generic_list *)&all_exts);
+        loader_destroy_generic_list(icd->this_instance,
+                                    (struct loader_generic_list *)&icd_exts);
     } else {
         /* just return the count; need to add in the count of implicit layer
          * extensions
diff --git a/loader/loader.h b/loader/loader.h
index 95803c0..cb5f206 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -30,8 +30,9 @@
 
 #include <vulkan/vulkan.h>
 #include "vk_loader_platform.h"
-
+#include "vk_loader_layer.h"
 #include <vulkan/vk_layer.h>
+
 #include <vulkan/vk_icd.h>
 #include <assert.h>
 
@@ -43,6 +44,9 @@
 #define LOADER_EXPORT
 #endif
 
+// A debug option to disable allocators at compile time to investigate future issues.
+#define DEBUG_DISABLE_APP_ALLOCATORS 0
+
 #define MAX_STRING_SIZE 1024
 #define VK_MAJOR(version) (version >> 22)
 #define VK_MINOR(version) ((version >> 12) & 0x3ff)
@@ -71,11 +75,11 @@
 static const char UTF8_DATA_BYTE_CODE = 0x80;
 static const char UTF8_DATA_BYTE_MASK = 0xC0;
 
-static const char std_validation_names[8][VK_MAX_EXTENSION_NAME_SIZE] = {
-    "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
-    "VK_LAYER_LUNARG_device_limits", "VK_LAYER_LUNARG_object_tracker",
-    "VK_LAYER_LUNARG_image", "VK_LAYER_LUNARG_core_validation",
-    "VK_LAYER_LUNARG_swapchain", "VK_LAYER_GOOGLE_unique_objects"};
+static const char std_validation_names[7][VK_MAX_EXTENSION_NAME_SIZE] = {
+    "VK_LAYER_GOOGLE_threading",       "VK_LAYER_LUNARG_parameter_validation",
+    "VK_LAYER_LUNARG_object_tracker",  "VK_LAYER_LUNARG_image",
+    "VK_LAYER_LUNARG_core_validation", "VK_LAYER_LUNARG_swapchain",
+     "VK_LAYER_GOOGLE_unique_objects"};
 
 // form of all dynamic lists/arrays
 // only the list element should be changed
@@ -169,6 +173,8 @@
 
     struct loader_layer_list activated_layer_list;
 
+    VkAllocationCallbacks alloc_callbacks;
+
     struct loader_device *next;
 };
 
@@ -392,14 +398,14 @@
 };
 
 /* helper function definitions */
-void *loader_heap_alloc(const struct loader_instance *instance, size_t size,
-                        VkSystemAllocationScope allocationScope);
-
-void loader_heap_free(const struct loader_instance *instance, void *pMemory);
-
-void *loader_tls_heap_alloc(size_t size);
-
-void loader_tls_heap_free(void *pMemory);
+void *loader_instance_heap_alloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocationScope);
+void loader_instance_heap_free(const struct loader_instance *instance, void *pMemory);
+void *loader_instance_heap_realloc(const struct loader_instance *instance, void *pMemory, size_t orig_size, size_t size, VkSystemAllocationScope alloc_scope);
+void *loader_instance_tls_heap_alloc(size_t size);
+void loader_instance_tls_heap_free(void *pMemory);
+void *loader_device_heap_alloc(const struct loader_device *device, size_t size, VkSystemAllocationScope allocationScope);
+void loader_device_heap_free(const struct loader_device *device, void *pMemory);
+void *loader_device_heap_realloc(const struct loader_device *device, void *pMemory, size_t orig_size, size_t size, VkSystemAllocationScope alloc_scope);
 
 void loader_log(const struct loader_instance *inst, VkFlags msg_type,
                 int32_t msg_code, const char *format, ...);
@@ -419,9 +425,9 @@
     const VkInstanceCreateInfo *pCreateInfo);
 
 void loader_initialize(void);
-void loader_copy_layer_properties(const struct loader_instance *inst,
-                                         struct loader_layer_properties *dst,
-                                         struct loader_layer_properties *src);
+VkResult loader_copy_layer_properties(const struct loader_instance *inst,
+                                      struct loader_layer_properties *dst,
+                                      struct loader_layer_properties *src);
 bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop,
                                      const uint32_t count,
                                      const VkExtensionProperties *ext_array);
@@ -449,12 +455,13 @@
 void loader_destroy_generic_list(const struct loader_instance *inst,
                                  struct loader_generic_list *list);
 void loader_destroy_layer_list(const struct loader_instance *inst,
+                               struct loader_device *device,
                                struct loader_layer_list *layer_list);
 void loader_delete_layer_properties(const struct loader_instance *inst,
                                     struct loader_layer_list *layer_list);
 bool loader_find_layer_name_array(const char *name, uint32_t layer_count,
                         const char layer_list[][VK_MAX_EXTENSION_NAME_SIZE]);
-void loader_expand_layer_names(
+VkResult loader_expand_layer_names(
     struct loader_instance *inst, const char *key_name,
     uint32_t expand_count,
     const char expand_names[][VK_MAX_EXTENSION_NAME_SIZE],
@@ -466,17 +473,17 @@
 void loader_delete_shadow_inst_layer_names(const struct loader_instance *inst,
                                            const VkInstanceCreateInfo *orig,
                                            VkInstanceCreateInfo *ours);
-void loader_add_to_layer_list(const struct loader_instance *inst,
-                              struct loader_layer_list *list,
-                              uint32_t prop_list_count,
-                              const struct loader_layer_properties *props);
+VkResult loader_add_to_layer_list(const struct loader_instance *inst,
+                                  struct loader_layer_list *list,
+                                  uint32_t prop_list_count,
+                                  const struct loader_layer_properties *props);
 void loader_find_layer_name_add_list(
     const struct loader_instance *inst, const char *name,
     const enum layer_type type, const struct loader_layer_list *search_list,
     struct loader_layer_list *found_list);
 void loader_scanned_icd_clear(const struct loader_instance *inst,
                               struct loader_icd_libs *icd_libs);
-void loader_icd_scan(const struct loader_instance *inst,
+VkResult loader_icd_scan(const struct loader_instance *inst,
                      struct loader_icd_libs *icds);
 void loader_layer_scan(const struct loader_instance *inst,
                        struct loader_layer_list *instance_layers);
@@ -493,15 +500,22 @@
 void *loader_get_dev_ext_trampoline(uint32_t index);
 struct loader_instance *loader_get_instance(const VkInstance instance);
 void loader_deactivate_layers(const struct loader_instance *instance,
+                              struct loader_device *device,
                               struct loader_layer_list *list);
 struct loader_device *
-loader_create_logical_device(const struct loader_instance *inst);
+loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator);
 void loader_add_logical_device(const struct loader_instance *inst,
                                struct loader_icd *icd,
                                struct loader_device *found_dev);
 void loader_remove_logical_device(const struct loader_instance *inst,
                                   struct loader_icd *icd,
-                                  struct loader_device *found_dev);
+                                  struct loader_device *found_dev,
+                                  const VkAllocationCallbacks *pAllocator);
+// NOTE: Outside of loader, this entry-point is only proivided for error cleanup.
+void loader_destroy_logical_device(const struct loader_instance *inst,
+                                   struct loader_device *dev,
+                                   const VkAllocationCallbacks *pAllocator);
+
 VkResult
 loader_enable_instance_layers(struct loader_instance *inst,
                               const VkInstanceCreateInfo *pCreateInfo,
diff --git a/loader/trampoline.c b/loader/trampoline.c
index 8b1117d..e2c3205 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -122,6 +122,7 @@
     struct loader_extension_list local_ext_list;
     struct loader_icd_libs icd_libs;
     uint32_t copy_size;
+    VkResult res = VK_SUCCESS;
 
     tls_instance = NULL;
     memset(&local_ext_list, 0, sizeof(local_ext_list));
@@ -134,7 +135,8 @@
             VK_STRING_ERROR_NONE) {
             assert(VK_FALSE && "vkEnumerateInstanceExtensionProperties:  "
                                "pLayerName is too long or is badly formed");
-            return VK_ERROR_EXTENSION_NOT_PRESENT;
+            res = VK_ERROR_EXTENSION_NOT_PRESENT;
+            goto out;
         }
 
         loader_layer_scan(NULL, &instance_layers);
@@ -154,7 +156,7 @@
                 loader_add_to_ext_list(NULL, &local_ext_list, ext_list->count,
                                        ext_list->list);
             }
-            loader_destroy_layer_list(NULL, &local_list);
+            loader_destroy_layer_list(NULL, NULL, &local_list);
             global_ext_list = &local_ext_list;
 
         } else {
@@ -170,7 +172,10 @@
     } else {
         /* Scan/discover all ICD libraries */
         memset(&icd_libs, 0, sizeof(struct loader_icd_libs));
-        loader_icd_scan(NULL, &icd_libs);
+        res = loader_icd_scan(NULL, &icd_libs);
+        if (VK_SUCCESS != res) {
+            goto out;
+        }
         /* get extensions from all ICD's, merge so no duplicates */
         loader_get_icd_loader_instance_extensions(NULL, &icd_libs,
                                                   &local_ext_list);
@@ -189,16 +194,13 @@
     }
 
     if (global_ext_list == NULL) {
-        loader_destroy_layer_list(NULL, &instance_layers);
-        return VK_ERROR_LAYER_NOT_PRESENT;
+        res = VK_ERROR_LAYER_NOT_PRESENT;
+        goto out;
     }
 
     if (pProperties == NULL) {
         *pPropertyCount = global_ext_list->count;
-        loader_destroy_layer_list(NULL, &instance_layers);
-        loader_destroy_generic_list(
-            NULL, (struct loader_generic_list *)&local_ext_list);
-        return VK_SUCCESS;
+        goto out;
     }
 
     copy_size = *pPropertyCount < global_ext_list->count
@@ -209,16 +211,16 @@
                sizeof(VkExtensionProperties));
     }
     *pPropertyCount = copy_size;
-    loader_destroy_generic_list(NULL,
-                                (struct loader_generic_list *)&local_ext_list);
 
     if (copy_size < global_ext_list->count) {
-        loader_destroy_layer_list(NULL, &instance_layers);
-        return VK_INCOMPLETE;
+        res = VK_INCOMPLETE;
+        goto out;
     }
 
-    loader_destroy_layer_list(NULL, &instance_layers);
-    return VK_SUCCESS;
+out:
+    loader_destroy_generic_list(NULL, (struct loader_generic_list *)&local_ext_list);
+    loader_delete_layer_properties(NULL, &instance_layers);
+    return res;
 }
 
 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
@@ -238,7 +240,7 @@
 
     if (pProperties == NULL) {
         *pPropertyCount = instance_layer_list.count;
-        loader_destroy_layer_list(NULL, &instance_layer_list);
+        loader_destroy_layer_list(NULL, NULL, &instance_layer_list);
         return VK_SUCCESS;
     }
 
@@ -251,50 +253,54 @@
     }
 
     *pPropertyCount = copy_size;
-    loader_destroy_layer_list(NULL, &instance_layer_list);
 
     if (copy_size < instance_layer_list.count) {
+        loader_destroy_layer_list(NULL, NULL, &instance_layer_list);
         return VK_INCOMPLETE;
     }
 
+    loader_destroy_layer_list(NULL, NULL, &instance_layer_list);
+
     return VK_SUCCESS;
 }
 
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
-                 const VkAllocationCallbacks *pAllocator,
-                 VkInstance *pInstance) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
+    const VkInstanceCreateInfo *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
     struct loader_instance *ptr_instance = NULL;
     VkInstance created_instance = VK_NULL_HANDLE;
+    bool loaderLocked = false;
     VkResult res = VK_ERROR_INITIALIZATION_FAILED;
 
     loader_platform_thread_once(&once_init, loader_initialize);
 
-    //TODO start handling the pAllocators again
-#if 0
-	if (pAllocator) {
-        ptr_instance = (struct loader_instance *) pAllocator->pfnAllocation(
-                           pAllocator->pUserData,
-                           sizeof(struct loader_instance),
-                           sizeof(int *),
-                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+    {
+#else
+    if (pAllocator) {
+        ptr_instance = (struct loader_instance *)pAllocator->pfnAllocation(
+            pAllocator->pUserData, sizeof(struct loader_instance),
+            sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     } else {
 #endif
-    ptr_instance =
-        (struct loader_instance *)malloc(sizeof(struct loader_instance));
-    //}
+        ptr_instance =
+            (struct loader_instance *)malloc(sizeof(struct loader_instance));
+    }
+
+    VkInstanceCreateInfo ici = *pCreateInfo;
+
     if (ptr_instance == NULL) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
     tls_instance = ptr_instance;
     loader_platform_thread_lock_mutex(&loader_lock);
+    loaderLocked = true;
     memset(ptr_instance, 0, sizeof(struct loader_instance));
-#if 0
     if (pAllocator) {
         ptr_instance->alloc_callbacks = *pAllocator;
     }
-#endif
 
     /*
      * Look for one or more debug report create info structures
@@ -309,9 +315,8 @@
                                         &ptr_instance->tmp_callbacks)) {
         // One or more were found, but allocation failed.  Therefore, clean up
         // and fail this function:
-        loader_heap_free(ptr_instance, ptr_instance);
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     } else if (ptr_instance->num_tmp_callbacks > 0) {
         // Setup the temporary callback(s) here to catch early issues:
         if (util_CreateDebugReportCallbacks(ptr_instance, pAllocator,
@@ -320,12 +325,8 @@
                                             ptr_instance->tmp_callbacks)) {
             // Failure of setting up one or more of the callback.  Therefore,
             // clean up and fail this function:
-            util_FreeDebugReportCreateInfos(pAllocator,
-                                            ptr_instance->tmp_dbg_create_infos,
-                                            ptr_instance->tmp_callbacks);
-            loader_heap_free(ptr_instance, ptr_instance);
-            loader_platform_thread_unlock_mutex(&loader_lock);
-            return VK_ERROR_OUT_OF_HOST_MEMORY;
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            goto out;
         }
     }
 
@@ -343,28 +344,26 @@
                                    pCreateInfo->ppEnabledLayerNames,
                                    &ptr_instance->instance_layer_list);
         if (res != VK_SUCCESS) {
-            util_DestroyDebugReportCallbacks(ptr_instance, pAllocator,
-                                             ptr_instance->num_tmp_callbacks,
-                                             ptr_instance->tmp_callbacks);
-            util_FreeDebugReportCreateInfos(pAllocator,
-                                            ptr_instance->tmp_dbg_create_infos,
-                                            ptr_instance->tmp_callbacks);
-            loader_heap_free(ptr_instance, ptr_instance);
-            loader_platform_thread_unlock_mutex(&loader_lock);
-            return res;
+            goto out;
         }
     }
 
     /* convert any meta layers to the actual layers makes a copy of layer name*/
-    VkInstanceCreateInfo ici = *pCreateInfo;
-    loader_expand_layer_names(
+    VkResult layerErr = loader_expand_layer_names(
         ptr_instance, std_validation_str,
         sizeof(std_validation_names) / sizeof(std_validation_names[0]),
         std_validation_names, &ici.enabledLayerCount, &ici.ppEnabledLayerNames);
+    if (VK_SUCCESS != layerErr) {
+        res = layerErr;
+        goto out;
+    }
 
     /* Scan/discover all ICD libraries */
     memset(&ptr_instance->icd_libs, 0, sizeof(ptr_instance->icd_libs));
-    loader_icd_scan(ptr_instance, &ptr_instance->icd_libs);
+    res = loader_icd_scan(ptr_instance, &ptr_instance->icd_libs);
+    if (res != VK_SUCCESS) {
+        goto out;
+    }
 
     /* get extensions from all ICD's, merge so no duplicates, then validate */
     loader_get_icd_loader_instance_extensions(
@@ -373,45 +372,15 @@
         ptr_instance, &ptr_instance->ext_list,
         &ptr_instance->instance_layer_list, &ici);
     if (res != VK_SUCCESS) {
-        loader_delete_shadow_inst_layer_names(ptr_instance, pCreateInfo, &ici);
-        loader_delete_layer_properties(ptr_instance,
-                                       &ptr_instance->instance_layer_list);
-        loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
-        loader_destroy_generic_list(
-            ptr_instance,
-            (struct loader_generic_list *)&ptr_instance->ext_list);
-        util_DestroyDebugReportCallbacks(ptr_instance, pAllocator,
-                                         ptr_instance->num_tmp_callbacks,
-                                         ptr_instance->tmp_callbacks);
-        util_FreeDebugReportCreateInfos(pAllocator,
-                                        ptr_instance->tmp_dbg_create_infos,
-                                        ptr_instance->tmp_callbacks);
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        loader_heap_free(ptr_instance, ptr_instance);
-        return res;
+        goto out;
     }
 
-    ptr_instance->disp =
-        loader_heap_alloc(ptr_instance, sizeof(VkLayerInstanceDispatchTable),
-                          VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    ptr_instance->disp = loader_instance_heap_alloc(
+        ptr_instance, sizeof(VkLayerInstanceDispatchTable),
+        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (ptr_instance->disp == NULL) {
-        loader_delete_shadow_inst_layer_names(ptr_instance, pCreateInfo, &ici);
-
-        loader_delete_layer_properties(ptr_instance,
-                                       &ptr_instance->instance_layer_list);
-        loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
-        loader_destroy_generic_list(
-            ptr_instance,
-            (struct loader_generic_list *)&ptr_instance->ext_list);
-        util_DestroyDebugReportCallbacks(ptr_instance, pAllocator,
-                                         ptr_instance->num_tmp_callbacks,
-                                         ptr_instance->tmp_callbacks);
-        util_FreeDebugReportCreateInfos(pAllocator,
-                                        ptr_instance->tmp_dbg_create_infos,
-                                        ptr_instance->tmp_callbacks);
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        loader_heap_free(ptr_instance, ptr_instance);
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
     memcpy(ptr_instance->disp, &instance_disp, sizeof(instance_disp));
     ptr_instance->next = loader.instances;
@@ -421,24 +390,7 @@
     res = loader_enable_instance_layers(ptr_instance, &ici,
                                         &ptr_instance->instance_layer_list);
     if (res != VK_SUCCESS) {
-        loader_delete_shadow_inst_layer_names(ptr_instance, pCreateInfo, &ici);
-        loader_delete_layer_properties(ptr_instance,
-                                       &ptr_instance->instance_layer_list);
-        loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
-        loader_destroy_generic_list(
-            ptr_instance,
-            (struct loader_generic_list *)&ptr_instance->ext_list);
-        loader.instances = ptr_instance->next;
-        util_DestroyDebugReportCallbacks(ptr_instance, pAllocator,
-                                         ptr_instance->num_tmp_callbacks,
-                                         ptr_instance->tmp_callbacks);
-        util_FreeDebugReportCreateInfos(pAllocator,
-                                        ptr_instance->tmp_dbg_create_infos,
-                                        ptr_instance->tmp_callbacks);
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        loader_heap_free(ptr_instance, ptr_instance->disp);
-        loader_heap_free(ptr_instance, ptr_instance);
-        return res;
+        goto out;
     }
 
     created_instance = (VkInstance)ptr_instance;
@@ -462,18 +414,57 @@
         // TODO: cleanup here.
     }
 
-    /* Remove temporary debug_report callback */
-    util_DestroyDebugReportCallbacks(ptr_instance, pAllocator,
-                                     ptr_instance->num_tmp_callbacks,
-                                     ptr_instance->tmp_callbacks);
-    loader_delete_shadow_inst_layer_names(ptr_instance, pCreateInfo, &ici);
-    loader_platform_thread_unlock_mutex(&loader_lock);
+out:
+
+    if (NULL != ptr_instance) {
+        if (res != VK_SUCCESS) {
+            if (NULL != ptr_instance->next) {
+                loader.instances = ptr_instance->next;
+            }
+            if (NULL != ptr_instance->disp) {
+                loader_instance_heap_free(ptr_instance, ptr_instance->disp);
+            }
+            if (ptr_instance->num_tmp_callbacks > 0) {
+                util_DestroyDebugReportCallbacks(
+                    ptr_instance, pAllocator, ptr_instance->num_tmp_callbacks,
+                    ptr_instance->tmp_callbacks);
+                util_FreeDebugReportCreateInfos(
+                    pAllocator, ptr_instance->tmp_dbg_create_infos,
+                    ptr_instance->tmp_callbacks);
+            }
+
+            loader_deactivate_layers(ptr_instance, NULL,
+                                     &ptr_instance->activated_layer_list);
+
+            loader_delete_shadow_inst_layer_names(ptr_instance, pCreateInfo,
+                                                  &ici);
+            loader_delete_layer_properties(ptr_instance,
+                                           &ptr_instance->instance_layer_list);
+            loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
+            loader_destroy_generic_list(
+                ptr_instance,
+                (struct loader_generic_list *)&ptr_instance->ext_list);
+
+            loader_instance_heap_free(ptr_instance, ptr_instance);
+        } else {
+            /* Remove temporary debug_report callback */
+            util_DestroyDebugReportCallbacks(ptr_instance, pAllocator,
+                                             ptr_instance->num_tmp_callbacks,
+                                             ptr_instance->tmp_callbacks);
+            loader_delete_shadow_inst_layer_names(ptr_instance, pCreateInfo,
+                                                  &ici);
+        }
+
+        if (loaderLocked) {
+            loader_platform_thread_unlock_mutex(&loader_lock);
+        }
+    }
+
     return res;
 }
 
-LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
-vkDestroyInstance(VkInstance instance,
-                  const VkAllocationCallbacks *pAllocator) {
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(
+    VkInstance instance, const VkAllocationCallbacks *pAllocator) {
     const VkLayerInstanceDispatchTable *disp;
     struct loader_instance *ptr_instance = NULL;
     bool callback_setup = false;
@@ -488,6 +479,10 @@
 
     ptr_instance = loader_get_instance(instance);
 
+    if (pAllocator) {
+        ptr_instance->alloc_callbacks = *pAllocator;
+    }
+
     if (ptr_instance->num_tmp_callbacks > 0) {
         // Setup the temporary callback(s) here to catch cleanup issues:
         if (!util_CreateDebugReportCallbacks(ptr_instance, pAllocator,
@@ -500,9 +495,11 @@
 
     disp->DestroyInstance(instance, pAllocator);
 
-    loader_deactivate_layers(ptr_instance, &ptr_instance->activated_layer_list);
-    if (ptr_instance->phys_devs)
-        loader_heap_free(ptr_instance, ptr_instance->phys_devs);
+    loader_deactivate_layers(ptr_instance, NULL,
+                             &ptr_instance->activated_layer_list);
+    if (ptr_instance->phys_devs) {
+        loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs);
+    }
     if (callback_setup) {
         util_DestroyDebugReportCallbacks(ptr_instance, pAllocator,
                                          ptr_instance->num_tmp_callbacks,
@@ -511,8 +508,8 @@
                                         ptr_instance->tmp_dbg_create_infos,
                                         ptr_instance->tmp_callbacks);
     }
-    loader_heap_free(ptr_instance, ptr_instance->disp);
-    loader_heap_free(ptr_instance, ptr_instance);
+    loader_instance_heap_free(ptr_instance, ptr_instance->disp);
+    loader_instance_heap_free(ptr_instance, ptr_instance);
     loader_platform_thread_unlock_mutex(&loader_lock);
 }
 
@@ -551,7 +548,7 @@
     *pPhysicalDeviceCount = count;
     if (!inst->phys_devs) {
         inst->phys_devs =
-            (struct loader_physical_device_tramp *)loader_heap_alloc(
+            (struct loader_physical_device_tramp *)loader_instance_heap_alloc(
                 inst, inst->total_gpu_count *
                           sizeof(struct loader_physical_device_tramp),
                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
@@ -643,14 +640,13 @@
                                             pMemoryProperties);
 }
 
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateDevice(VkPhysicalDevice physicalDevice,
-               const VkDeviceCreateInfo *pCreateInfo,
-               const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(
+    VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
     VkResult res;
-    struct loader_physical_device_tramp *phys_dev;
-    struct loader_device *dev;
-    struct loader_instance *inst;
+    struct loader_physical_device_tramp *phys_dev = NULL;
+    struct loader_device *dev = NULL;
+    struct loader_instance *inst = NULL;
 
     assert(pCreateInfo->queueCreateInfoCount >= 1);
 
@@ -661,52 +657,51 @@
 
     /* Get the physical device (ICD) extensions  */
     struct loader_extension_list icd_exts;
+    icd_exts.list = NULL;
     if (!loader_init_generic_list(inst, (struct loader_generic_list *)&icd_exts,
                                   sizeof(VkExtensionProperties))) {
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
     res = loader_add_device_extensions(
         inst, inst->disp->EnumerateDeviceExtensionProperties,
         phys_dev->phys_dev, "Unknown", &icd_exts);
     if (res != VK_SUCCESS) {
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        return res;
+        goto out;
     }
 
     /* make sure requested extensions to be enabled are supported */
-    res = loader_validate_device_extensions(phys_dev, &inst->activated_layer_list,
-                                            &icd_exts, pCreateInfo);
+    res = loader_validate_device_extensions(
+        phys_dev, &inst->activated_layer_list, &icd_exts, pCreateInfo);
     if (res != VK_SUCCESS) {
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        return res;
+        goto out;
     }
 
-    dev = loader_create_logical_device(inst);
+    dev = loader_create_logical_device(inst, pAllocator);
     if (dev == NULL) {
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
     /* copy the instance layer list into the device */
     dev->activated_layer_list.capacity = inst->activated_layer_list.capacity;
     dev->activated_layer_list.count = inst->activated_layer_list.count;
-    dev->activated_layer_list.list = loader_heap_alloc(inst,
-                            inst->activated_layer_list.capacity,
-                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    dev->activated_layer_list.list =
+        loader_device_heap_alloc(dev, inst->activated_layer_list.capacity,
+                                 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
     if (dev->activated_layer_list.list == NULL) {
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
     memcpy(dev->activated_layer_list.list, inst->activated_layer_list.list,
-            sizeof(*dev->activated_layer_list.list) * dev->activated_layer_list.count);
+           sizeof(*dev->activated_layer_list.list) *
+               dev->activated_layer_list.count);
 
-
-    res = loader_create_device_chain(phys_dev, pCreateInfo, pAllocator, inst, dev);
+    res = loader_create_device_chain(phys_dev, pCreateInfo, pAllocator, inst,
+                                     dev);
     if (res != VK_SUCCESS) {
-        loader_platform_thread_unlock_mutex(&loader_lock);
-        return res;
+        goto out;
     }
 
     *pDevice = dev->device;
@@ -721,6 +716,19 @@
         &dev->loader_dispatch,
         dev->loader_dispatch.core_dispatch.GetDeviceProcAddr, *pDevice);
 
+out:
+
+    // Failure cleanup
+    if (VK_SUCCESS != res) {
+        if (NULL != dev) {
+            loader_destroy_logical_device(inst, dev, pAllocator);
+        }
+    }
+
+    if (NULL != icd_exts.list) {
+        loader_destroy_generic_list(inst,
+                                    (struct loader_generic_list *)&icd_exts);
+    }
     loader_platform_thread_unlock_mutex(&loader_lock);
     return res;
 }
@@ -742,7 +750,7 @@
 
     disp->DestroyDevice(device, pAllocator);
     dev->device = NULL;
-    loader_remove_logical_device(inst, icd, dev);
+    loader_remove_logical_device(inst, icd, dev, pAllocator);
 
     loader_platform_thread_unlock_mutex(&loader_lock);
 }
@@ -880,7 +888,7 @@
         enabled_layers->count = count;
         enabled_layers->capacity = enabled_layers->count *
                                  sizeof(struct loader_layer_properties);
-        enabled_layers->list = loader_heap_alloc(inst, enabled_layers->capacity,
+        enabled_layers->list = loader_instance_heap_alloc(inst, enabled_layers->capacity,
                                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
         if (!enabled_layers->list)
             return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -893,14 +901,21 @@
                     std_val_count, std_validation_names)) {
                 struct loader_layer_properties props;
                 loader_init_std_validation_props(&props);
-                loader_copy_layer_properties(inst,
-                                             &enabled_layers->list[j], &props);
+                VkResult err = loader_copy_layer_properties(inst,
+                                                            &enabled_layers->list[j],
+                                                            &props);
+                if (err != VK_SUCCESS) {
+                    return err;
+                }
                 i += std_val_count;
             }
             else {
-                loader_copy_layer_properties(inst,
-                                         &enabled_layers->list[j],
-                                         &inst->activated_layer_list.list[i++]);
+                VkResult err = loader_copy_layer_properties(inst,
+                                                            &enabled_layers->list[j],
+                                                            &inst->activated_layer_list.list[i++]);
+                if (err != VK_SUCCESS) {
+                    return err;
+                }
             }
         }
     }
@@ -916,8 +931,9 @@
     }
     *pPropertyCount = copy_size;
 
-    if (inst->activated_layers_are_std_val)
+    if (inst->activated_layers_are_std_val) {
         loader_delete_layer_properties(inst, enabled_layers);
+    }
     if (copy_size < count) {
         loader_platform_thread_unlock_mutex(&loader_lock);
         return VK_INCOMPLETE;
@@ -2014,7 +2030,7 @@
 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
 vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
                   VkDeviceSize dstOffset, VkDeviceSize dataSize,
-                  const uint32_t *pData) {
+                  const void *pData) {
     const VkLayerDispatchTable *disp;
 
     disp = loader_get_dispatch(commandBuffer);
diff --git a/loader/vk_loader_layer.h b/loader/vk_loader_layer.h
new file mode 100644
index 0000000..2207c02
--- /dev/null
+++ b/loader/vk_loader_layer.h
@@ -0,0 +1,32 @@
+/*
+*
+* Copyright (c) 2016 The Khronos Group Inc.
+* Copyright (c) 2016 Valve Corporation
+* Copyright (c) 2016 LunarG, Inc.
+*
+* Licensed under the Apache 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
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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: Mark Lobodzinski <mark@lunarg.com>
+*
+*/
+#pragma once
+
+// Linked list node for tree of debug callback functions
+typedef struct VkLayerDbgFunctionNode_ {
+    VkDebugReportCallbackEXT msgCallback;
+    PFN_vkDebugReportCallbackEXT pfnMsgCallback;
+    VkFlags msgFlags;
+    void *pUserData;
+    struct VkLayerDbgFunctionNode_ *pNext;
+} VkLayerDbgFunctionNode;
+
diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h
index c94e33c..3a02640 100644
--- a/loader/vk_loader_platform.h
+++ b/loader/vk_loader_platform.h
@@ -50,42 +50,23 @@
 #define PATH_SEPERATOR ':'
 #define DIRECTORY_SYMBOL '/'
 
-#define VULKAN_ICDCONF_DIR                                                     \
-    "/"                                                                        \
-    "vulkan"                                                                   \
-    "/"                                                                        \
-    "icd.d"
-#define VULKAN_ICD_DIR                                                         \
-    "/"                                                                        \
-    "vulkan"                                                                   \
-    "/"                                                                        \
-    "icd"
-#define VULKAN_ELAYERCONF_DIR                                                  \
-    "/"                                                                        \
-    "vulkan"                                                                   \
-    "/"                                                                        \
-    "explicit_layer.d"
-#define VULKAN_ILAYERCONF_DIR                                                  \
-    "/"                                                                        \
-    "vulkan"                                                                   \
-    "/"                                                                        \
-    "implicit_layer.d"
-#define VULKAN_LAYER_DIR                                                       \
-    "/"                                                                        \
-    "vulkan"                                                                   \
-    "/"                                                                        \
-    "layer"
+#define VULKAN_DIR            "/vulkan/"
+#define VULKAN_ICDCONF_DIR    "icd.d"
+#define VULKAN_ICD_DIR        "icd"
+#define VULKAN_ELAYERCONF_DIR "explicit_layer.d"
+#define VULKAN_ILAYERCONF_DIR "implicit_layer.d"
+#define VULKAN_LAYER_DIR      "layer"
 
 #if defined(LOCALPREFIX)
 #define LOCAL_DRIVERS_INFO                                                     \
-    LOCALPREFIX "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" LOCALPREFIX              \
-                "/" DATADIR VULKAN_ICDCONF_DIR ":"
+    LOCALPREFIX "/" SYSCONFDIR VULKAN_DIR VULKAN_ICDCONF_DIR ":"               \
+    LOCALPREFIX "/" DATADIR    VULKAN_DIR VULKAN_ICDCONF_DIR ":"
 #define LOCAL_ELAYERS_INFO                                                     \
-    LOCALPREFIX "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" LOCALPREFIX           \
-                "/" DATADIR VULKAN_ELAYERCONF_DIR ":"
+    LOCALPREFIX "/" SYSCONFDIR VULKAN_DIR VULKAN_ELAYERCONF_DIR ":"            \
+    LOCALPREFIX "/" DATADIR    VULKAN_DIR VULKAN_ELAYERCONF_DIR ":"
 #define LOCAL_ILAYERS_INFO                                                     \
-    LOCALPREFIX "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" LOCALPREFIX           \
-                "/" DATADIR VULKAN_ILAYERCONF_DIR ":"
+    LOCALPREFIX "/" SYSCONFDIR VULKAN_DIR VULKAN_ILAYERCONF_DIR ":"            \
+    LOCALPREFIX "/" DATADIR    VULKAN_DIR VULKAN_ILAYERCONF_DIR ":"
 #else
 #define LOCAL_DRIVERS_INFO
 #define LOCAL_ELAYERS_INFO
@@ -94,25 +75,25 @@
 
 #define DEFAULT_VK_DRIVERS_INFO                                                \
     LOCAL_DRIVERS_INFO                                                         \
-    "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":"                                      \
-    "/usr/" DATADIR VULKAN_ICDCONF_DIR
+    "/"  SYSCONFDIR VULKAN_DIR VULKAN_ICDCONF_DIR ":"                          \
+    "/usr/" DATADIR VULKAN_DIR VULKAN_ICDCONF_DIR
 #define DEFAULT_VK_DRIVERS_PATH ""
 #define DEFAULT_VK_ELAYERS_INFO                                                \
     LOCAL_ELAYERS_INFO                                                         \
-    "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":"                                   \
-    "/usr/" DATADIR VULKAN_ELAYERCONF_DIR
+    "/"  SYSCONFDIR VULKAN_DIR VULKAN_ELAYERCONF_DIR ":"                       \
+    "/usr/" DATADIR VULKAN_DIR VULKAN_ELAYERCONF_DIR
 #define DEFAULT_VK_ILAYERS_INFO                                                \
     LOCAL_ILAYERS_INFO                                                         \
-    "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":"                                   \
-    "/usr/" DATADIR VULKAN_ILAYERCONF_DIR
+    "/"  SYSCONFDIR VULKAN_DIR VULKAN_ILAYERCONF_DIR ":"                       \
+    "/usr/" DATADIR VULKAN_DIR VULKAN_ILAYERCONF_DIR
 #define DEFAULT_VK_LAYERS_PATH ""
 #if !defined(LAYERS_SOURCE_PATH)
 #define LAYERS_SOURCE_PATH NULL
 #endif
 #define LAYERS_PATH_ENV "VK_LAYER_PATH"
-#define HOME_VK_DRIVERS_INFO "/.local/share" VULKAN_ICDCONF_DIR
-#define HOME_VK_ELAYERS_INFO "/.local/share" VULKAN_ELAYERCONF_DIR
-#define HOME_VK_ILAYERS_INFO "/.local/share" VULKAN_ILAYERCONF_DIR
+#define HOME_VK_DRIVERS_INFO VULKAN_DIR VULKAN_ICDCONF_DIR
+#define HOME_VK_ELAYERS_INFO VULKAN_DIR VULKAN_ELAYERCONF_DIR
+#define HOME_VK_ILAYERS_INFO VULKAN_DIR VULKAN_ILAYERCONF_DIR
 
 // C99:
 #define PRINTF_SIZE_T_SPECIFIER "%zu"
@@ -136,12 +117,6 @@
     return dirname(path);
 }
 
-// Environment variables
-
-static inline char *loader_getenv(const char *name) { return getenv(name); }
-
-static inline void loader_free_getenv(const char *val) {}
-
 // Dynamic Loading of libraries:
 typedef void *loader_platform_dl_handle;
 static inline loader_platform_dl_handle
@@ -322,29 +297,6 @@
     return current;
 }
 
-// Environment variables
-
-static inline char *loader_getenv(const char *name) {
-    char *retVal;
-    DWORD valSize;
-
-    valSize = GetEnvironmentVariableA(name, NULL, 0);
-
-    // valSize DOES include the null terminator, so for any set variable
-    // will always be at least 1. If it's 0, the variable wasn't set.
-    if (valSize == 0)
-        return NULL;
-
-    // TODO; FIXME This should be using any app defined memory allocation
-    retVal = (char *)malloc(valSize);
-
-    GetEnvironmentVariableA(name, retVal, valSize);
-
-    return retVal;
-}
-
-static inline void loader_free_getenv(const char *val) { free((void *)val); }
-
 // Dynamic Loading:
 typedef HMODULE loader_platform_dl_handle;
 static loader_platform_dl_handle
@@ -352,8 +304,8 @@
     return LoadLibrary(libPath);
 }
 static char *loader_platform_open_library_error(const char *libPath) {
-    static char errorMsg[120];
-    snprintf(errorMsg, 119, "Failed to open dynamic library \"%s\"", libPath);
+    static char errorMsg[164];
+    snprintf(errorMsg, 163, "Failed to open dynamic library \"%s\"", libPath);
     return errorMsg;
 }
 static void loader_platform_close_library(loader_platform_dl_handle library) {
diff --git a/loader/wsi.c b/loader/wsi.c
index 3182a58..9bac94b 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -214,7 +214,7 @@
                              const VkAllocationCallbacks *pAllocator) {
     struct loader_instance *ptr_instance = loader_get_instance(instance);
 
-    loader_heap_free(ptr_instance, (void *)surface);
+    loader_instance_heap_free(ptr_instance, (void *)surface);
 }
 
 /*
@@ -431,11 +431,9 @@
  * This is the trampoline entrypoint
  * for CreateSwapchainKHR
  */
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateSwapchainKHR(VkDevice device,
-                     const VkSwapchainCreateInfoKHR *pCreateInfo,
-                     const VkAllocationCallbacks *pAllocator,
-                     VkSwapchainKHR *pSwapchain) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
+    VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
     const VkLayerDispatchTable *disp;
     disp = loader_get_dispatch(device);
     VkResult res =
@@ -507,11 +505,9 @@
  * This is the trampoline entrypoint
  * for CreateWin32SurfaceKHR
  */
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateWin32SurfaceKHR(VkInstance instance,
-                        const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
-                        const VkAllocationCallbacks *pAllocator,
-                        VkSurfaceKHR *pSurface) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
+    VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     const VkLayerInstanceDispatchTable *disp;
     disp = loader_get_instance_dispatch(instance);
     VkResult res;
@@ -525,25 +521,24 @@
  * This is the instance chain terminator function
  * for CreateWin32SurfaceKHR
  */
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_CreateWin32SurfaceKHR(VkInstance instance,
-                                 const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
-                                 const VkAllocationCallbacks *pAllocator,
-                                 VkSurfaceKHR *pSurface) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(
+    VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_win32_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_win32_surface extension not enabled.  "
                    "vkCreateWin32SurfaceKHR not executed!\n");
-        return VK_SUCCESS;
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
     // Next, if so, proceed with the implementation of this function:
     VkIcdSurfaceWin32 *pIcdSurface = NULL;
 
-    pIcdSurface = loader_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceWin32),
-                                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface =
+        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceWin32),
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -615,11 +610,9 @@
  * This is the trampoline entrypoint
  * for CreateMirSurfaceKHR
  */
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateMirSurfaceKHR(VkInstance instance,
-                      const VkMirSurfaceCreateInfoKHR *pCreateInfo,
-                      const VkAllocationCallbacks *pAllocator,
-                      VkSurfaceKHR *pSurface) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
+    VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     const VkLayerInstanceDispatchTable *disp;
     disp = loader_get_instance_dispatch(instance);
     VkResult res;
@@ -633,25 +626,24 @@
  * This is the instance chain terminator function
  * for CreateMirSurfaceKHR
  */
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_CreateMirSurfaceKHR(VkInstance instance,
-                               const VkMirSurfaceCreateInfoKHR *pCreateInfo,
-                               const VkAllocationCallbacks *pAllocator,
-                               VkSurfaceKHR *pSurface) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMirSurfaceKHR(
+    VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_mir_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_mir_surface extension not enabled.  "
                    "vkCreateMirSurfaceKHR not executed!\n");
-        return VK_SUCCESS;
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
     // Next, if so, proceed with the implementation of this function:
     VkIcdSurfaceMir *pIcdSurface = NULL;
 
-    pIcdSurface = loader_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceMir),
-                                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface =
+        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceMir),
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -752,14 +744,15 @@
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_wayland_surface extension not enabled.  "
                    "vkCreateWaylandSurfaceKHR not executed!\n");
-        return VK_SUCCESS;
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
     // Next, if so, proceed with the implementation of this function:
     VkIcdSurfaceWayland *pIcdSurface = NULL;
 
-    pIcdSurface = loader_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceWayland),
-                                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface =
+        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceWayland),
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -833,11 +826,9 @@
  * This is the trampoline entrypoint
  * for CreateXcbSurfaceKHR
  */
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateXcbSurfaceKHR(VkInstance instance,
-                      const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
-                      const VkAllocationCallbacks *pAllocator,
-                      VkSurfaceKHR *pSurface) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
+    VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     const VkLayerInstanceDispatchTable *disp;
     disp = loader_get_instance_dispatch(instance);
     VkResult res;
@@ -851,25 +842,24 @@
  * This is the instance chain terminator function
  * for CreateXcbSurfaceKHR
  */
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_CreateXcbSurfaceKHR(VkInstance instance,
-                               const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
-                               const VkAllocationCallbacks *pAllocator,
-                               VkSurfaceKHR *pSurface) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(
+    VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_xcb_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_xcb_surface extension not enabled.  "
                    "vkCreateXcbSurfaceKHR not executed!\n");
-        return VK_SUCCESS;
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
     // Next, if so, proceed with the implementation of this function:
     VkIcdSurfaceXcb *pIcdSurface = NULL;
 
-    pIcdSurface = loader_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceXcb),
-                                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface =
+        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceXcb),
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -944,11 +934,9 @@
  * This is the trampoline entrypoint
  * for CreateXlibSurfaceKHR
  */
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateXlibSurfaceKHR(VkInstance instance,
-                       const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
-                       const VkAllocationCallbacks *pAllocator,
-                       VkSurfaceKHR *pSurface) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
+    VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     const VkLayerInstanceDispatchTable *disp;
     disp = loader_get_instance_dispatch(instance);
     VkResult res;
@@ -962,25 +950,24 @@
  * This is the instance chain terminator function
  * for CreateXlibSurfaceKHR
  */
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_CreateXlibSurfaceKHR(VkInstance instance,
-                                const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
-                                const VkAllocationCallbacks *pAllocator,
-                                VkSurfaceKHR *pSurface) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(
+    VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_xlib_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_xlib_surface extension not enabled.  "
                    "vkCreateXlibSurfaceKHR not executed!\n");
-        return VK_SUCCESS;
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
     // Next, if so, proceed with the implementation of this function:
     VkIcdSurfaceXlib *pIcdSurface = NULL;
 
-    pIcdSurface = loader_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceXlib),
-                                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface =
+        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceXlib),
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -1054,10 +1041,9 @@
  * This is the trampoline entrypoint
  * for CreateAndroidSurfaceKHR
  */
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateAndroidSurfaceKHR(VkInstance instance, ANativeWindow *window,
-                          const VkAllocationCallbacks *pAllocator,
-                          VkSurfaceKHR *pSurface) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
+    VkInstance instance, ANativeWindow *window,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     const VkLayerInstanceDispatchTable *disp;
     disp = loader_get_instance_dispatch(instance);
     VkResult res;
@@ -1070,24 +1056,24 @@
  * This is the instance chain terminator function
  * for CreateAndroidSurfaceKHR
  */
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_CreateAndroidSurfaceKHR(VkInstance instance, Window window,
-                                   const VkAllocationCallbacks *pAllocator,
-                                   VkSurfaceKHR *pSurface) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(
+    VkInstance instance, Window window, const VkAllocationCallbacks *pAllocator,
+    VkSurfaceKHR *pSurface) {
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_display_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_display extension not enabled.  "
                    "vkCreateAndroidSurfaceKHR not executed!\n");
-        return VK_SUCCESS;
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
     // Next, if so, proceed with the implementation of this function:
     VkIcdSurfaceAndroid *pIcdSurface = NULL;
 
-    pIcdSurface = loader_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceAndroid),
-                                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface =
+        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceAndroid),
+                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -1264,11 +1250,10 @@
                                             pPropertyCount, pProperties);
 }
 
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
-                       const VkDisplayModeCreateInfoKHR *pCreateInfo,
-                       const VkAllocationCallbacks *pAllocator,
-                       VkDisplayModeKHR *pMode) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(
+    VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+    const VkDisplayModeCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
     VkPhysicalDevice unwrapped_phys_dev =
         loader_unwrap_physical_device(physicalDevice);
     const VkLayerInstanceDispatchTable *disp;
@@ -1278,12 +1263,10 @@
     return res;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice,
-                                VkDisplayKHR display,
-                                const VkDisplayModeCreateInfoKHR *pCreateInfo,
-                                const VkAllocationCallbacks *pAllocator,
-                                VkDisplayModeKHR *pMode) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(
+    VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+    const VkDisplayModeCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
     // First, check to ensure the appropriate extension was enabled:
     struct loader_physical_device *phys_dev =
         (struct loader_physical_device *)physicalDevice;
@@ -1293,7 +1276,7 @@
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_display extension not enabled.  "
                    "vkCreateDisplayModeKHR not executed!\n");
-        return VK_SUCCESS;
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
     // Next, if so, proceed with the implementation of this function:
@@ -1344,11 +1327,9 @@
                                                planeIndex, pCapabilities);
 }
 
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,
-                               const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
-                               const VkAllocationCallbacks *pAllocator,
-                               VkSurfaceKHR *pSurface) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(
+    VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     const VkLayerInstanceDispatchTable *disp;
     disp = loader_get_instance_dispatch(instance);
     VkResult res;
@@ -1368,11 +1349,11 @@
         loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_surface extension not enabled.  "
                    "vkCreateDisplayPlaneSurfaceKHR not executed!\n");
-        return VK_SUCCESS;
+        return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
-    pIcdSurface = loader_heap_alloc(inst, sizeof(VkIcdSurfaceDisplay),
-                                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface = loader_instance_heap_alloc(
+        inst, sizeof(VkIcdSurfaceDisplay), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
diff --git a/spirv-headers_revision b/spirv-headers_revision
new file mode 100644
index 0000000..74846cc
--- /dev/null
+++ b/spirv-headers_revision
@@ -0,0 +1 @@
+3814effb879ab5a98a7b9288a4b4c7849d2bc8ac
diff --git a/spirv-tools_revision b/spirv-tools_revision
index fa8390b..9aaac77 100644
--- a/spirv-tools_revision
+++ b/spirv-tools_revision
@@ -1 +1 @@
-0d512bbef58dfcdb1a6bcde7fe17fcc4a33a1aa7
+6c61bf2dfadf70ab5fe1b0fb918ba03b7afa2396
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 66e2d3d..c74c2de 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -26,7 +26,7 @@
     endif()
 
 else()
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare -std=c++11")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
 endif()
 
 set (LIBGLM_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/libs)
@@ -51,6 +51,8 @@
     if (NOT (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR))
         add_custom_target(binary-dir-symlinks ALL
             COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/run_all_tests.sh
+            COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/run_wrap_objects_tests.sh
+            COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/run_loader_tests.sh
             COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/vkvalidatelayerdoc.sh
             VERBATIM
             )
@@ -92,3 +94,4 @@
 target_link_libraries(vk_loader_validation_tests ${LIBVK} gtest gtest_main VkLayer_utils ${GLSLANG_LIBRARIES})
 
 add_subdirectory(gtest-1.7.0)
+add_subdirectory(layers)
diff --git a/tests/_run_all_tests.ps1 b/tests/_run_all_tests.ps1
index cb3acba..0dc014b 100755
--- a/tests/_run_all_tests.ps1
+++ b/tests/_run_all_tests.ps1
@@ -1,16 +1,35 @@
-# Be sure to run "Set-ExecutionPolicy RemoteSigned" before running powershell scripts

-

-Param([switch]$Debug)

-

-if ($Debug) {

-    $dPath = "Debug"

-} else {

-    $dPath = "Release"

-}

-

-Set-Item -path env:Path -value ($env:Path + ";..\loader\$dPath")

-Set-Item -path env:Path -value ($env:Path + ";gtest-1.7.0\$dPath")

-$env:VK_LAYER_PATH = "..\layers\$dPath"

-

-& $dPath\vk_layer_validation_tests

-.\vkvalidatelayerdoc.ps1

+# Be sure to run "Set-ExecutionPolicy RemoteSigned" before running powershell scripts
+
+# Use TestExceptions to filter out tests with known problems, separated by a colon
+# i.e. run_all_tests.ps1 -TestExceptions VkLayerTest.RequiredParameter:VkLayerTest.UnrecognizedValue
+
+# To trigger Debug tests, specify the parameter with a hyphen
+# i.e  run_all_tests.ps1 -Debug
+
+Param(
+    [switch]$Debug,
+    [string]$TestExceptions
+)
+
+if ($Debug) {
+    $dPath = "Debug"
+} else {
+    $dPath = "Release"
+}
+
+Set-Item -path env:Path -value ($env:Path + ";..\loader\$dPath")
+Set-Item -path env:Path -value ($env:Path + ";gtest-1.7.0\$dPath")
+$env:VK_LAYER_PATH = "..\layers\$dPath"
+
+& $dPath\vk_loader_validation_tests
+if ($lastexitcode -ne 0) {
+   exit 1
+}
+
+& $dPath\vk_layer_validation_tests --gtest_filter=-$TestExceptions
+if ($lastexitcode -ne 0) {
+   exit 1
+}
+
+.\vkvalidatelayerdoc.ps1
+exit $lastexitcode
diff --git a/tests/_vkvalidatelayerdoc.ps1 b/tests/_vkvalidatelayerdoc.ps1
index cdd7150..39351dc 100644
--- a/tests/_vkvalidatelayerdoc.ps1
+++ b/tests/_vkvalidatelayerdoc.ps1
@@ -1,33 +1,34 @@
-# Powershell script for running the vktrace trace/replay auto test

-# To run this test:

-#    cd <this-dir>

-#    powershell C:\src\LoaderAndTools\vktracereplay.ps1 [-Debug]

-

-if ($args[0] -eq "-Debug") {

-    $dPath = "Debug"

-} else {

-    $dPath = "Release"

-}

-

-write-host -background black -foreground green "[  RUN     ] " -nonewline

-write-host "vkvalidatelayerdoc.ps1: Validate layer documentation"

-

-# Run doc validation from project root dir

-push-location ..\..

-

-# Validate that layer documentation matches source contents

-python vk_layer_documentation_generate.py --validate

-

-# Report result based on exit code

-if (!$LASTEXITCODE) {

-    write-host -background black -foreground green "[  PASSED  ] " -nonewline;

-    $exitstatus = 0

-} else {

-    echo 'Validation of vk_validation_layer_details.md failed'

-    write-host -background black -foreground red "[  FAILED  ] "  -nonewline;

-    echo '1 FAILED TEST'

-    $exitstatus = 1

-}

-

-pop-location

-exit $exitstatus

+# Powershell script for running the layer validation details doc validator
+# To run this test:
+#    From a Windows powershell:
+#    cd C:\src\Vulkan-LoaderAndValidationLayers\build\tests
+#    .\vkvalidatelayerdoc.ps1 [-Debug]
+
+if ($args[0] -eq "-Debug") {
+    $dPath = "Debug"
+} else {
+    $dPath = "Release"
+}
+
+write-host -background black -foreground green "[  RUN     ] " -nonewline
+write-host "vkvalidatelayerdoc.ps1: Validate layer documentation"
+
+# Run doc validation from project root dir
+push-location ..\..
+
+# Validate that layer documentation matches source contents
+python vk_layer_documentation_generate.py --validate
+
+# Report result based on exit code
+if (!$LASTEXITCODE) {
+    write-host -background black -foreground green "[  PASSED  ] " -nonewline;
+    $exitstatus = 0
+} else {
+    echo 'Validation of vk_validation_layer_details.md failed'
+    write-host -background black -foreground red "[  FAILED  ] "  -nonewline;
+    echo '1 FAILED TEST'
+    $exitstatus = 1
+}
+
+pop-location
+exit $exitstatus
diff --git a/tests/gtest-1.7.0/include/gtest/gtest.h b/tests/gtest-1.7.0/include/gtest/gtest.h
index 6fa0a39..f147b2d 100644
--- a/tests/gtest-1.7.0/include/gtest/gtest.h
+++ b/tests/gtest-1.7.0/include/gtest/gtest.h
@@ -1445,6 +1445,11 @@
                                 // signed/unsigned mismatch.
 #endif
 
+#if defined(__GNUC__) || defined(__GNUG__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#endif
+
   if (expected == actual) {
     return AssertionSuccess();
   }
@@ -1453,6 +1458,10 @@
 # pragma warning(pop)          // Restores the warning state.
 #endif
 
+#if defined(__GNUC__) || defined(__GNUG__)
+#pragma GCC diagnostic pop
+#endif
+
   return EqFailure(expected_expression,
                    actual_expression,
                    FormatForComparisonFailureMessage(expected, actual),
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index dc8f774..60aeb2e 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -17,6 +17,7 @@
  * Author: Mike Stroyan <mike@LunarG.com>
  * Author: Tobin Ehlis <tobine@google.com>
  * Author: Tony Barbour <tony@LunarG.com>
+ * Author: Cody Northrop <cnorthrop@google.com>
  */
 
 #ifdef ANDROID
@@ -24,6 +25,12 @@
 #else
 #include <vulkan/vulkan.h>
 #endif
+
+#if defined(ANDROID) && defined(VALIDATION_APK)
+#include <android/log.h>
+#include <android_native_app_glue.h>
+#endif
+
 #include "test_common.h"
 #include "vkrenderframework.h"
 #include "vk_layer_config.h"
@@ -63,6 +70,8 @@
     BsoFailStencilReadMask = 0x00000040,
     BsoFailStencilWriteMask = 0x00000080,
     BsoFailStencilReference = 0x00000100,
+    BsoFailCmdClearAttachments = 0x00000200,
+    BsoFailIndexBuffer = 0x00000400,
 } BsoFailSelect;
 
 struct vktriangle_vs_uniform {
@@ -98,6 +107,7 @@
           uint64_t srcObject, size_t location, int32_t msgCode,
           const char *pLayerPrefix, const char *pMsg, void *pUserData);
 
+
 // ********************************************************
 // ErrorMonitor Usage:
 //
@@ -131,24 +141,22 @@
         test_platform_thread_unlock_mutex(&m_mutex);
     }
 
-    VkBool32 CheckForDesiredMsg(VkFlags msgFlags, const char *msgString) {
+    VkBool32 CheckForDesiredMsg(const char *msgString) {
         VkBool32 result = VK_FALSE;
         test_platform_thread_lock_mutex(&m_mutex);
         if (m_bailout != NULL) {
             *m_bailout = true;
         }
         string errorString(msgString);
-        if (msgFlags & m_msgFlags) {
-            if (errorString.find(m_desiredMsg) != string::npos) {
-                if (m_msgFound) { /* if multiple matches, don't lose all but the last! */
-                    m_otherMsgs.push_back(m_failureMsg);
-                }
-                m_failureMsg = errorString;
-                m_msgFound = VK_TRUE;
-                result = VK_TRUE;
-            } else {
-                m_otherMsgs.push_back(errorString);
+        if (errorString.find(m_desiredMsg) != string::npos) {
+            if (m_msgFound) { // If multiple matches, don't lose all but the last!
+                m_otherMsgs.push_back(m_failureMsg);
             }
+            m_failureMsg = errorString;
+            m_msgFound = VK_TRUE;
+            result = VK_TRUE;
+        } else {
+            m_otherMsgs.push_back(errorString);
         }
         test_platform_thread_unlock_mutex(&m_mutex);
         return result;
@@ -158,6 +166,8 @@
 
     string GetFailureMsg(void) { return m_failureMsg; }
 
+    VkDebugReportFlagsEXT GetMessageFlags(void) { return m_msgFlags; }
+
     VkBool32 DesiredMsgFound(void) { return m_msgFound; }
 
     void SetBailout(bool *bailout) { m_bailout = bailout; }
@@ -170,11 +180,13 @@
         }
     }
 
-    /* helpers */
+    // Helpers
 
-    void ExpectSuccess() {
-        // match anything
-        SetDesiredFailureMsg(~0u, "");
+    // ExpectSuccess now takes an optional argument allowing a custom combination of debug flags
+    void ExpectSuccess(VkDebugReportFlagsEXT message_flag_mask = VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+        m_msgFlags = message_flag_mask;
+        // Match ANY message matching specified type
+        SetDesiredFailureMsg(message_flag_mask, "");
     }
 
     void VerifyFound() {
@@ -209,11 +221,9 @@
 myDbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
           uint64_t srcObject, size_t location, int32_t msgCode,
           const char *pLayerPrefix, const char *pMsg, void *pUserData) {
-    if (msgFlags &
-        (VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
-         VK_DEBUG_REPORT_ERROR_BIT_EXT)) {
-        ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
-        return errMonitor->CheckForDesiredMsg(msgFlags, pMsg);
+    ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
+    if (msgFlags & errMonitor->GetMessageFlags()) {
+        return errMonitor->CheckForDesiredMsg(pMsg);
     }
     return false;
 }
@@ -251,7 +261,8 @@
         m_commandBuffer->DrawIndexed(indexCount, instanceCount, firstIndex,
                                      vertexOffset, firstInstance);
     }
-    void QueueCommandBuffer() { m_commandBuffer->QueueCommandBuffer(); }
+    void QueueCommandBuffer(bool checkSuccess = true) {
+        m_commandBuffer->QueueCommandBuffer(checkSuccess); }
     void QueueCommandBuffer(const VkFence &fence) {
         m_commandBuffer->QueueCommandBuffer(fence);
     }
@@ -269,7 +280,6 @@
 
     virtual void SetUp() {
         std::vector<const char *> instance_layer_names;
-        std::vector<const char *> device_layer_names;
         std::vector<const char *> instance_extension_names;
         std::vector<const char *> device_extension_names;
 
@@ -285,20 +295,10 @@
         instance_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation");
         instance_layer_names.push_back("VK_LAYER_LUNARG_object_tracker");
         instance_layer_names.push_back("VK_LAYER_LUNARG_core_validation");
-        instance_layer_names.push_back("VK_LAYER_LUNARG_device_limits");
         instance_layer_names.push_back("VK_LAYER_LUNARG_image");
         instance_layer_names.push_back("VK_LAYER_LUNARG_swapchain");
         instance_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects");
 
-        device_layer_names.push_back("VK_LAYER_GOOGLE_threading");
-        device_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation");
-        device_layer_names.push_back("VK_LAYER_LUNARG_object_tracker");
-        device_layer_names.push_back("VK_LAYER_LUNARG_core_validation");
-        device_layer_names.push_back("VK_LAYER_LUNARG_device_limits");
-        device_layer_names.push_back("VK_LAYER_LUNARG_image");
-        device_layer_names.push_back("VK_LAYER_LUNARG_swapchain");
-        device_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects");
-
         if (m_enableWSI) {
             instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
             device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
@@ -332,9 +332,8 @@
         this->app_info.apiVersion = VK_API_VERSION_1_0;
 
         m_errorMonitor = new ErrorMonitor;
-        InitFramework(instance_layer_names, device_layer_names,
-                      instance_extension_names, device_extension_names,
-                      myDbgFunc, m_errorMonitor);
+        InitFramework(instance_layer_names, instance_extension_names,
+                      device_extension_names, myDbgFunc, m_errorMonitor);
     }
 
     virtual void TearDown() {
@@ -482,7 +481,22 @@
     GenericDrawPreparation(pipelineobj, descriptorSet, failMask);
 
     // render triangle
-    Draw(3, 1, 0, 0);
+    if (failMask & BsoFailIndexBuffer) {
+        // Use DrawIndexed w/o an index buffer bound
+        DrawIndexed(3, 1, 0, 0, 0);
+    } else {
+        Draw(3, 1, 0, 0);
+    }
+
+    if (failMask & BsoFailCmdClearAttachments) {
+        VkClearAttachment color_attachment = {};
+        color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        color_attachment.colorAttachment = 1; // Someone who knew what they were doing would use 0 for the index;
+        VkClearRect clear_rect = {{{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}}, 0, 0};
+
+        vkCmdClearAttachments(m_commandBuffer->GetBufferHandle(), 1,
+                              &color_attachment, 1, &clear_rect);
+    }
 
     // finalize recording of the command buffer
     EndCommandBuffer();
@@ -522,6 +536,8 @@
     ds_ci.depthBoundsTestEnable = VK_FALSE;
     if (failMask & BsoFailDepthBounds) {
         ds_ci.depthBoundsTestEnable = VK_TRUE;
+        ds_ci.maxDepthBounds = 0.0f;
+        ds_ci.minDepthBounds = 0.0f;
     }
     ds_ci.stencilTestEnable = VK_TRUE;
     ds_ci.front = stencil;
@@ -546,6 +562,268 @@
     }
 };
 
+class VkBufferTest {
+public:
+    enum eTestEnFlags {
+        eDoubleDelete,
+        eInvalidDeviceOffset,
+        eInvalidMemoryOffset,
+        eBindNullBuffer,
+        eFreeInvalidHandle,
+    };
+
+    enum eTestConditions {
+        eOffsetAlignment = 1
+    };
+
+    static bool GetTestConditionValid(VkDeviceObj *aVulkanDevice,
+                                      eTestEnFlags aTestFlag,
+                                      VkBufferUsageFlags aBufferUsage = 0) {
+        if (eInvalidDeviceOffset != aTestFlag &&
+                eInvalidMemoryOffset != aTestFlag) {
+            return true;
+        }
+        VkDeviceSize offset_limit = 0;
+        if (eInvalidMemoryOffset == aTestFlag) {
+            VkBuffer vulkanBuffer;
+            VkBufferCreateInfo buffer_create_info = {};
+            buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+            buffer_create_info.size = 32;
+            buffer_create_info.usage = aBufferUsage;
+
+            vkCreateBuffer(aVulkanDevice->device(), &buffer_create_info, nullptr,
+                           &vulkanBuffer);
+            VkMemoryRequirements memory_reqs = {0};
+
+            vkGetBufferMemoryRequirements(aVulkanDevice->device(),
+                                          vulkanBuffer, &memory_reqs);
+            vkDestroyBuffer(aVulkanDevice->device(), vulkanBuffer, nullptr);
+            offset_limit = memory_reqs.alignment;
+        }
+        else if ((VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
+             VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) & aBufferUsage) {
+            offset_limit =
+                    aVulkanDevice->props.limits.minTexelBufferOffsetAlignment;
+        } else if (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT & aBufferUsage) {
+            offset_limit =
+                    aVulkanDevice->props.limits.minUniformBufferOffsetAlignment;
+        } else if (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT & aBufferUsage) {
+            offset_limit =
+                    aVulkanDevice->props.limits.minStorageBufferOffsetAlignment;
+        }
+        if (eOffsetAlignment < offset_limit) {
+            return true;
+        }
+        return false;
+    }
+
+    // A constructor which performs validation tests within construction.
+    VkBufferTest(VkDeviceObj *aVulkanDevice,
+                 VkBufferUsageFlags aBufferUsage,
+                 eTestEnFlags aTestFlag)
+        : AllocateCurrent(false), BoundCurrent(false),
+        CreateCurrent(false), VulkanDevice(aVulkanDevice->device()) {
+
+        if (eBindNullBuffer == aTestFlag) {
+            VulkanMemory = 0;
+            vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory, 0);
+        } else {
+            VkBufferCreateInfo buffer_create_info = {};
+            buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+            buffer_create_info.size = 32;
+            buffer_create_info.usage = aBufferUsage;
+
+            vkCreateBuffer(VulkanDevice, &buffer_create_info, nullptr,
+                           &VulkanBuffer);
+
+            CreateCurrent = true;
+
+            VkMemoryRequirements memory_requirements;
+            vkGetBufferMemoryRequirements(VulkanDevice, VulkanBuffer,
+                                          &memory_requirements);
+
+            VkMemoryAllocateInfo memory_allocate_info = {};
+            memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+            memory_allocate_info.allocationSize = memory_requirements.size;
+            bool pass = aVulkanDevice->phy().
+                    set_memory_type(memory_requirements.memoryTypeBits,
+                                    &memory_allocate_info,
+                                    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+            if (!pass) {
+                vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
+                return;
+            }
+
+            vkAllocateMemory(VulkanDevice, &memory_allocate_info, NULL,
+                             &VulkanMemory);
+            AllocateCurrent = true;
+            // NB: 1 is intentionally an invalid offset value
+            const bool offset_en = eInvalidDeviceOffset == aTestFlag ||
+                    eInvalidMemoryOffset == aTestFlag;
+            vkBindBufferMemory(VulkanDevice, VulkanBuffer, VulkanMemory,
+                               offset_en ? eOffsetAlignment : 0);
+            BoundCurrent = true;
+
+            InvalidDeleteEn = (eFreeInvalidHandle == aTestFlag);
+        }
+    }
+
+    ~VkBufferTest() {
+        if (CreateCurrent) {
+            vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
+        }
+        if (AllocateCurrent) {
+            if (InvalidDeleteEn) {
+                union {
+                    VkDeviceMemory device_memory;
+                    unsigned long long index_access;
+                } bad_index;
+
+                bad_index.device_memory = VulkanMemory;
+                bad_index.index_access++;
+
+                vkFreeMemory(VulkanDevice,
+                             bad_index.device_memory,
+                             nullptr);
+            }
+            vkFreeMemory(VulkanDevice, VulkanMemory, nullptr);
+        }
+    }
+
+    bool GetBufferCurrent() {
+        return AllocateCurrent && BoundCurrent && CreateCurrent;
+    }
+
+    const VkBuffer &GetBuffer() {
+        return VulkanBuffer;
+    }
+
+    void TestDoubleDestroy() {
+        // Destroy the buffer but leave the flag set, which will cause
+        // the buffer to be destroyed again in the destructor.
+        vkDestroyBuffer(VulkanDevice, VulkanBuffer, nullptr);
+    }
+
+protected:
+    bool AllocateCurrent;
+    bool BoundCurrent;
+    bool CreateCurrent;
+    bool InvalidDeleteEn;
+
+    VkBuffer VulkanBuffer;
+    VkDevice VulkanDevice;
+    VkDeviceMemory VulkanMemory;
+
+};
+
+class VkVerticesObj {
+public:
+    VkVerticesObj(VkDeviceObj *aVulkanDevice, unsigned aAttributeCount,
+                  unsigned aBindingCount, unsigned aByteStride,
+                  VkDeviceSize aVertexCount, const float *aVerticies)
+        : BoundCurrent(false),
+          AttributeCount(aAttributeCount),
+          BindingCount(aBindingCount),
+          BindId(BindIdGenerator),
+          PipelineVertexInputStateCreateInfo(),
+          VulkanMemoryBuffer(aVulkanDevice, 1,
+                             static_cast<int>(aByteStride * aVertexCount),
+                             reinterpret_cast<const void *>(aVerticies),
+                             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) {
+        BindIdGenerator++; // NB: This can wrap w/misuse
+
+        VertexInputAttributeDescription =
+                new VkVertexInputAttributeDescription[AttributeCount];
+        VertexInputBindingDescription =
+                new VkVertexInputBindingDescription[BindingCount];
+
+        PipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions =
+                VertexInputAttributeDescription;
+        PipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount =
+                AttributeCount;
+        PipelineVertexInputStateCreateInfo.pVertexBindingDescriptions =
+                VertexInputBindingDescription;
+        PipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount =
+                BindingCount;
+        PipelineVertexInputStateCreateInfo.sType =
+                VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+
+        unsigned i = 0;
+        do {
+            VertexInputAttributeDescription[i].binding = BindId;
+            VertexInputAttributeDescription[i].location = i;
+            VertexInputAttributeDescription[i].format =
+                    VK_FORMAT_R32G32B32_SFLOAT;
+            VertexInputAttributeDescription[i].offset =
+                    sizeof(float) * aByteStride;
+            i++;
+        } while (AttributeCount < i);
+
+        i = 0;
+        do {
+            VertexInputBindingDescription[i].binding = BindId;
+            VertexInputBindingDescription[i].stride = aByteStride;
+            VertexInputBindingDescription[i].inputRate =
+                    VK_VERTEX_INPUT_RATE_VERTEX;
+            i++;
+        } while (BindingCount < i);
+    }
+
+    ~VkVerticesObj() {
+        if (VertexInputAttributeDescription) {
+            delete[] VertexInputAttributeDescription;
+        }
+        if (VertexInputBindingDescription) {
+            delete[] VertexInputBindingDescription;
+        }
+    }
+
+    bool AddVertexInputToPipe(VkPipelineObj &aPipelineObj) {
+        aPipelineObj.AddVertexInputAttribs(VertexInputAttributeDescription,
+                                           AttributeCount);
+        aPipelineObj.AddVertexInputBindings(VertexInputBindingDescription,
+                                            BindingCount);
+        return true;
+    }
+
+    void BindVertexBuffers(VkCommandBuffer aCommandBuffer,
+                           unsigned aOffsetCount = 0,
+                           VkDeviceSize *aOffsetList = nullptr) {
+        VkDeviceSize *offsetList;
+        unsigned offsetCount;
+
+        if (aOffsetCount) {
+            offsetList = aOffsetList;
+            offsetCount = aOffsetCount;
+        } else {
+            offsetList = new VkDeviceSize[1]();
+            offsetCount = 1;
+        }
+
+        vkCmdBindVertexBuffers(aCommandBuffer, BindId, offsetCount,
+                               &VulkanMemoryBuffer.handle(), offsetList);
+        BoundCurrent = true;
+
+        if (!aOffsetCount) {
+            delete [] offsetList;
+        }
+    }
+
+protected:
+    static uint32_t BindIdGenerator;
+
+    bool BoundCurrent;
+    unsigned AttributeCount;
+    unsigned BindingCount;
+    uint32_t BindId;
+
+    VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo;
+    VkVertexInputAttributeDescription *VertexInputAttributeDescription;
+    VkVertexInputBindingDescription *VertexInputBindingDescription;
+    VkConstantBufferObj VulkanMemoryBuffer;
+};
+
+uint32_t VkVerticesObj::BindIdGenerator;
 // ********************************************************************************************************************
 // ********************************************************************************************************************
 // ********************************************************************************************************************
@@ -698,127 +976,118 @@
     ASSERT_NO_FATAL_FAILURE(InitState());
 
     m_errorMonitor->SetDesiredFailureMsg(
-        VK_DEBUG_REPORT_ERROR_BIT_EXT,
-        "value of pAllocateInfo->pNext must be NULL");
+        VK_DEBUG_REPORT_WARNING_BIT_EXT,
+        "value of pCreateInfo->pNext must be NULL");
     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be
-    // NULL
+    // NULL.
+    // Need to pick a function that has no allowed pNext structure types.
+    // Expected to trigger an error with
+    // parameter_validation::validate_struct_pnext
+    VkEvent event = VK_NULL_HANDLE;
+    VkEventCreateInfo event_alloc_info = {};
+    // Zero-initialization will provide the correct sType
+    VkApplicationInfo app_info = {};
+    event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+    event_alloc_info.pNext = &app_info;
+    vkCreateEvent(device(), &event_alloc_info, NULL, &event);
+    m_errorMonitor->VerifyFound();
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_WARNING_BIT_EXT,
+        " chain includes a structure with unexpected VkStructureType ");
+    // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
+    // a function that has allowed pNext structure types and specify
+    // a structure type that is not allowed.
     // Expected to trigger an error with
     // parameter_validation::validate_struct_pnext
     VkDeviceMemory memory = VK_NULL_HANDLE;
-    // Zero-initialization will provide the correct sType
-    VkApplicationInfo app_info = {};
     VkMemoryAllocateInfo memory_alloc_info = {};
     memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
     memory_alloc_info.pNext = &app_info;
     vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory);
     m_errorMonitor->VerifyFound();
 
-    m_errorMonitor->SetDesiredFailureMsg(
-        VK_DEBUG_REPORT_ERROR_BIT_EXT,
-        " chain includes a structure with unexpected VkStructureType ");
-    // Set VkGraphicsPipelineCreateInfo::VkPipelineRasterizationStateCreateInfo::pNext to an invalid structure, when pNext is allowed to be a non-NULL value
-    // Expected to trigger an error with
-    // parameter_validation::validate_struct_pnext
-    VkDescriptorPoolSize ds_type_count = {};
-    ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
-    ds_type_count.descriptorCount = 1;
-
-    VkDescriptorPoolCreateInfo ds_pool_ci = {};
-    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
-    ds_pool_ci.pNext = NULL;
-    ds_pool_ci.maxSets = 1;
-    ds_pool_ci.poolSizeCount = 1;
-    ds_pool_ci.pPoolSizes = &ds_type_count;
-
-    VkDescriptorPool ds_pool;
-    VkResult err =
-        vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    // Positive test to check parameter_validation and unique_objects support
+    // for NV_dedicated_allocation
+    uint32_t extension_count = 0;
+    bool supports_nv_dedicated_allocation = false;
+    VkResult err = vkEnumerateDeviceExtensionProperties(
+        gpu(), nullptr, &extension_count, nullptr);
     ASSERT_VK_SUCCESS(err);
 
-    VkDescriptorSetLayoutBinding dsl_binding = {};
-    dsl_binding.binding = 0;
-    dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
-    dsl_binding.descriptorCount = 1;
-    dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
-    dsl_binding.pImmutableSamplers = NULL;
+    if (extension_count > 0) {
+        std::vector<VkExtensionProperties> available_extensions(
+            extension_count);
 
-    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
-    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
-    ds_layout_ci.pNext = NULL;
-    ds_layout_ci.bindingCount = 1;
-    ds_layout_ci.pBindings = &dsl_binding;
+        err = vkEnumerateDeviceExtensionProperties(
+            gpu(), nullptr, &extension_count, &available_extensions[0]);
+        ASSERT_VK_SUCCESS(err);
 
-    VkDescriptorSetLayout ds_layout;
-    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
-        &ds_layout);
-    ASSERT_VK_SUCCESS(err);
+        for (const auto &extension_props : available_extensions) {
+            if (strcmp(extension_props.extensionName,
+                       VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0) {
+                supports_nv_dedicated_allocation = true;
+            }
+        }
+    }
 
-    VkDescriptorSet descriptorSet;
-    VkDescriptorSetAllocateInfo ds_alloc_info = {};
-    ds_alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
-    ds_alloc_info.descriptorSetCount = 1;
-    ds_alloc_info.descriptorPool = ds_pool;
-    ds_alloc_info.pSetLayouts = &ds_layout;
-    err = vkAllocateDescriptorSets(m_device->device(), &ds_alloc_info,
-        &descriptorSet);
-    ASSERT_VK_SUCCESS(err);
+    if (supports_nv_dedicated_allocation) {
+        m_errorMonitor->ExpectSuccess();
 
-    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
-    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
-    pipeline_layout_ci.setLayoutCount = 1;
-    pipeline_layout_ci.pSetLayouts = &ds_layout;
+        VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info =
+            {};
+        dedicated_buffer_create_info.sType =
+            VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
+        dedicated_buffer_create_info.pNext = nullptr;
+        dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
 
-    VkPipelineLayout pipeline_layout;
-    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
-        &pipeline_layout);
-    ASSERT_VK_SUCCESS(err);
+        uint32_t queue_family_index = 0;
+        VkBufferCreateInfo buffer_create_info = {};
+        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        buffer_create_info.pNext = &dedicated_buffer_create_info;
+        buffer_create_info.size = 1024;
+        buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+        buffer_create_info.queueFamilyIndexCount = 1;
+        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
 
-    VkViewport vp = {}; // Just need dummy vp to point to
-    VkRect2D sc = {};   // dummy scissor to point to
+        VkBuffer buffer;
+        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info,
+                                      NULL, &buffer);
+        ASSERT_VK_SUCCESS(err);
 
-    VkPipelineViewportStateCreateInfo vp_state_ci = {};
-    vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
-    vp_state_ci.scissorCount = 1;
-    vp_state_ci.pScissors = &sc;
-    vp_state_ci.viewportCount = 1;
-    vp_state_ci.pViewports = &vp;
+        VkMemoryRequirements memory_reqs;
+        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
 
-    VkPipelineRasterizationStateCreateInfo rs_state_ci = {};
-    rs_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
-    rs_state_ci.polygonMode = VK_POLYGON_MODE_FILL;
-    rs_state_ci.cullMode = VK_CULL_MODE_BACK_BIT;
-    rs_state_ci.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
-    rs_state_ci.depthClampEnable = VK_FALSE;
-    rs_state_ci.rasterizerDiscardEnable = VK_FALSE;
-    rs_state_ci.depthBiasEnable = VK_FALSE;
+        VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
+        dedicated_memory_info.sType =
+            VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
+        dedicated_memory_info.pNext = nullptr;
+        dedicated_memory_info.buffer = buffer;
+        dedicated_memory_info.image = VK_NULL_HANDLE;
 
-    VkGraphicsPipelineCreateInfo gp_ci = {};
-    gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
-    gp_ci.pViewportState = &vp_state_ci;
-    gp_ci.pRasterizationState = &rs_state_ci;
-    gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
-    gp_ci.layout = pipeline_layout;
-    gp_ci.renderPass = renderPass();
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = &dedicated_memory_info;
+        memory_info.allocationSize = memory_reqs.size;
 
-    VkPipelineCacheCreateInfo pc_ci = {};
-    pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
-    pc_ci.initialDataSize = 0;
-    pc_ci.pInitialData = 0;
+        bool pass;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits,
+                                               &memory_info, 0);
+        ASSERT_TRUE(pass);
 
-    VkPipeline pipeline;
-    VkPipelineCache pipelineCache;
+        VkDeviceMemory buffer_memory;
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL,
+                               &buffer_memory);
+        ASSERT_VK_SUCCESS(err);
 
-    err =
-        vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
-    ASSERT_VK_SUCCESS(err);
+        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+        ASSERT_VK_SUCCESS(err);
 
-    // Set VkPipelineRasterizationStateCreateInfo::pNext to an invalid value
-    VkApplicationInfo invalid_pnext_struct = {};
-    rs_state_ci.pNext = &invalid_pnext_struct;
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        vkFreeMemory(m_device->device(), buffer_memory, NULL);
 
-    vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
-        &gp_ci, NULL, &pipeline);
-    m_errorMonitor->VerifyFound();
+        m_errorMonitor->VerifyNotFound();
+    }
 }
 
 TEST_F(VkLayerTest, UnrecognizedValue) {
@@ -930,6 +1199,475 @@
         m_errorMonitor->VerifyFound();
     }
 }
+
+TEST_F(VkLayerTest, UpdateBufferAlignment) {
+    TEST_DESCRIPTION("Check alignment parameters for vkCmdUpdateBuffer");
+    uint32_t updateData[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+    vk_testing::Buffer buffer;
+    buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
+
+    BeginCommandBuffer();
+    // Introduce failure by using dstOffset that is not multiple of 4
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " is not a multiple of 4");
+    m_commandBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData);
+    m_errorMonitor->VerifyFound();
+
+    // Introduce failure by using dataSize that is not multiple of 4
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " is not a multiple of 4");
+    m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData);
+    m_errorMonitor->VerifyFound();
+
+    // Introduce failure by using dataSize that is < 0
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "must be greater than zero and less than or equal to 65536");
+    m_commandBuffer->UpdateBuffer(buffer.handle(), 0, -44, updateData);
+    m_errorMonitor->VerifyFound();
+
+    // Introduce failure by using dataSize that is > 65536
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "must be greater than zero and less than or equal to 65536");
+    m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 80000, updateData);
+    m_errorMonitor->VerifyFound();
+
+    EndCommandBuffer();
+}
+
+TEST_F(VkLayerTest, FillBufferAlignment) {
+    TEST_DESCRIPTION("Check alignment parameters for vkCmdFillBuffer");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+    vk_testing::Buffer buffer;
+    buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
+
+    BeginCommandBuffer();
+
+    // Introduce failure by using dstOffset that is not multiple of 4
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " is not a multiple of 4");
+    m_commandBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111);
+    m_errorMonitor->VerifyFound();
+
+    // Introduce failure by using size that is not multiple of 4
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " is not a multiple of 4");
+    m_commandBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111);
+    m_errorMonitor->VerifyFound();
+
+    // Introduce failure by using size that is zero
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "must be greater than zero");
+    m_commandBuffer->FillBuffer(buffer.handle(), 0, 0, 0x11111111);
+    m_errorMonitor->VerifyFound();
+
+    EndCommandBuffer();
+}
+
+// This is a positive test. No failures are expected.
+TEST_F(VkLayerTest, IgnoreUnrelatedDescriptor) {
+    TEST_DESCRIPTION("Ensure that the vkUpdateDescriptorSet validation code "
+                     "is ignoring VkWriteDescriptorSet members that are not "
+                     "related to the descriptor type specified by "
+                     "VkWriteDescriptorSet::descriptorType.  Correct "
+                     "validation behavior will result in the test running to "
+                     "completion without validation errors.");
+
+    const uintptr_t invalid_ptr = 0xcdcdcdcd;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // Image Case
+    {
+        m_errorMonitor->ExpectSuccess();
+
+        VkImage image;
+        const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
+        const int32_t tex_width = 32;
+        const int32_t tex_height = 32;
+        VkImageCreateInfo image_create_info = {};
+        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        image_create_info.pNext = NULL;
+        image_create_info.imageType = VK_IMAGE_TYPE_2D;
+        image_create_info.format = tex_format;
+        image_create_info.extent.width = tex_width;
+        image_create_info.extent.height = tex_height;
+        image_create_info.extent.depth = 1;
+        image_create_info.mipLevels = 1;
+        image_create_info.arrayLayers = 1;
+        image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+        image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+        image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+        image_create_info.flags = 0;
+        VkResult err =
+            vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+        ASSERT_VK_SUCCESS(err);
+
+        VkMemoryRequirements memory_reqs;
+        VkDeviceMemory image_memory;
+        bool pass;
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = NULL;
+        memory_info.allocationSize = 0;
+        memory_info.memoryTypeIndex = 0;
+        vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
+        memory_info.allocationSize = memory_reqs.size;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits,
+                                               &memory_info, 0);
+        ASSERT_TRUE(pass);
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL,
+                               &image_memory);
+        ASSERT_VK_SUCCESS(err);
+        err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
+        ASSERT_VK_SUCCESS(err);
+
+        VkImageViewCreateInfo image_view_create_info = {};
+        image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+        image_view_create_info.image = image;
+        image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+        image_view_create_info.format = tex_format;
+        image_view_create_info.subresourceRange.layerCount = 1;
+        image_view_create_info.subresourceRange.baseMipLevel = 0;
+        image_view_create_info.subresourceRange.levelCount = 1;
+        image_view_create_info.subresourceRange.aspectMask =
+            VK_IMAGE_ASPECT_COLOR_BIT;
+
+        VkImageView view;
+        err = vkCreateImageView(m_device->device(), &image_view_create_info,
+                                NULL, &view);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorPoolSize ds_type_count = {};
+        ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+        ds_type_count.descriptorCount = 1;
+
+        VkDescriptorPoolCreateInfo ds_pool_ci = {};
+        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+        ds_pool_ci.pNext = NULL;
+        ds_pool_ci.maxSets = 1;
+        ds_pool_ci.poolSizeCount = 1;
+        ds_pool_ci.pPoolSizes = &ds_type_count;
+
+        VkDescriptorPool ds_pool;
+        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL,
+                                     &ds_pool);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSetLayoutBinding dsl_binding = {};
+        dsl_binding.binding = 0;
+        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+        dsl_binding.descriptorCount = 1;
+        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+        dsl_binding.pImmutableSamplers = NULL;
+
+        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+        ds_layout_ci.sType =
+            VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        ds_layout_ci.pNext = NULL;
+        ds_layout_ci.bindingCount = 1;
+        ds_layout_ci.pBindings = &dsl_binding;
+        VkDescriptorSetLayout ds_layout;
+        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci,
+                                          NULL, &ds_layout);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSet descriptor_set;
+        VkDescriptorSetAllocateInfo alloc_info = {};
+        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+        alloc_info.descriptorSetCount = 1;
+        alloc_info.descriptorPool = ds_pool;
+        alloc_info.pSetLayouts = &ds_layout;
+        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info,
+                                       &descriptor_set);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorImageInfo image_info = {};
+        image_info.imageView = view;
+        image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+        VkWriteDescriptorSet descriptor_write;
+        memset(&descriptor_write, 0, sizeof(descriptor_write));
+        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        descriptor_write.dstSet = descriptor_set;
+        descriptor_write.dstBinding = 0;
+        descriptor_write.descriptorCount = 1;
+        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+        descriptor_write.pImageInfo = &image_info;
+
+        // Set pBufferInfo and pTexelBufferView to invalid values, which should
+        // be
+        //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
+        // This will most likely produce a crash if the parameter_validation
+        // layer
+        // does not correctly ignore pBufferInfo.
+        descriptor_write.pBufferInfo =
+            reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
+        descriptor_write.pTexelBufferView =
+            reinterpret_cast<const VkBufferView *>(invalid_ptr);
+
+        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0,
+                               NULL);
+
+        m_errorMonitor->VerifyNotFound();
+
+        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+        vkDestroyImageView(m_device->device(), view, NULL);
+        vkDestroyImage(m_device->device(), image, NULL);
+        vkFreeMemory(m_device->device(), image_memory, NULL);
+    }
+
+    // Buffer Case
+    {
+        m_errorMonitor->ExpectSuccess();
+
+        VkBuffer buffer;
+        uint32_t queue_family_index = 0;
+        VkBufferCreateInfo buffer_create_info = {};
+        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        buffer_create_info.size = 1024;
+        buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+        buffer_create_info.queueFamilyIndexCount = 1;
+        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+
+        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info,
+                                      NULL, &buffer);
+        ASSERT_VK_SUCCESS(err);
+
+        VkMemoryRequirements memory_reqs;
+        VkDeviceMemory buffer_memory;
+        bool pass;
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = NULL;
+        memory_info.allocationSize = 0;
+        memory_info.memoryTypeIndex = 0;
+
+        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
+        memory_info.allocationSize = memory_reqs.size;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits,
+                                               &memory_info, 0);
+        ASSERT_TRUE(pass);
+
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL,
+                               &buffer_memory);
+        ASSERT_VK_SUCCESS(err);
+        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorPoolSize ds_type_count = {};
+        ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        ds_type_count.descriptorCount = 1;
+
+        VkDescriptorPoolCreateInfo ds_pool_ci = {};
+        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+        ds_pool_ci.pNext = NULL;
+        ds_pool_ci.maxSets = 1;
+        ds_pool_ci.poolSizeCount = 1;
+        ds_pool_ci.pPoolSizes = &ds_type_count;
+
+        VkDescriptorPool ds_pool;
+        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL,
+                                     &ds_pool);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSetLayoutBinding dsl_binding = {};
+        dsl_binding.binding = 0;
+        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        dsl_binding.descriptorCount = 1;
+        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+        dsl_binding.pImmutableSamplers = NULL;
+
+        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+        ds_layout_ci.sType =
+            VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        ds_layout_ci.pNext = NULL;
+        ds_layout_ci.bindingCount = 1;
+        ds_layout_ci.pBindings = &dsl_binding;
+        VkDescriptorSetLayout ds_layout;
+        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci,
+                                          NULL, &ds_layout);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSet descriptor_set;
+        VkDescriptorSetAllocateInfo alloc_info = {};
+        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+        alloc_info.descriptorSetCount = 1;
+        alloc_info.descriptorPool = ds_pool;
+        alloc_info.pSetLayouts = &ds_layout;
+        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info,
+                                       &descriptor_set);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorBufferInfo buffer_info = {};
+        buffer_info.buffer = buffer;
+        buffer_info.offset = 0;
+        buffer_info.range = 1024;
+
+        VkWriteDescriptorSet descriptor_write;
+        memset(&descriptor_write, 0, sizeof(descriptor_write));
+        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        descriptor_write.dstSet = descriptor_set;
+        descriptor_write.dstBinding = 0;
+        descriptor_write.descriptorCount = 1;
+        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        descriptor_write.pBufferInfo = &buffer_info;
+
+        // Set pImageInfo and pTexelBufferView to invalid values, which should
+        // be
+        //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
+        // This will most likely produce a crash if the parameter_validation
+        // layer
+        // does not correctly ignore pImageInfo.
+        descriptor_write.pImageInfo =
+            reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
+        descriptor_write.pTexelBufferView =
+            reinterpret_cast<const VkBufferView *>(invalid_ptr);
+
+        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0,
+                               NULL);
+
+        m_errorMonitor->VerifyNotFound();
+
+        vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
+        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        vkFreeMemory(m_device->device(), buffer_memory, NULL);
+    }
+
+    // Texel Buffer Case
+    {
+        m_errorMonitor->ExpectSuccess();
+
+        VkBuffer buffer;
+        uint32_t queue_family_index = 0;
+        VkBufferCreateInfo buffer_create_info = {};
+        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        buffer_create_info.size = 1024;
+        buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
+        buffer_create_info.queueFamilyIndexCount = 1;
+        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+
+        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info,
+                                      NULL, &buffer);
+        ASSERT_VK_SUCCESS(err);
+
+        VkMemoryRequirements memory_reqs;
+        VkDeviceMemory buffer_memory;
+        bool pass;
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = NULL;
+        memory_info.allocationSize = 0;
+        memory_info.memoryTypeIndex = 0;
+
+        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
+        memory_info.allocationSize = memory_reqs.size;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits,
+                                               &memory_info, 0);
+        ASSERT_TRUE(pass);
+
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL,
+                               &buffer_memory);
+        ASSERT_VK_SUCCESS(err);
+        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+        ASSERT_VK_SUCCESS(err);
+
+        VkBufferViewCreateInfo buff_view_ci = {};
+        buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+        buff_view_ci.buffer = buffer;
+        buff_view_ci.format = VK_FORMAT_R8_UNORM;
+        buff_view_ci.range = VK_WHOLE_SIZE;
+        VkBufferView buffer_view;
+        err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL,
+                                 &buffer_view);
+
+        VkDescriptorPoolSize ds_type_count = {};
+        ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+        ds_type_count.descriptorCount = 1;
+
+        VkDescriptorPoolCreateInfo ds_pool_ci = {};
+        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+        ds_pool_ci.pNext = NULL;
+        ds_pool_ci.maxSets = 1;
+        ds_pool_ci.poolSizeCount = 1;
+        ds_pool_ci.pPoolSizes = &ds_type_count;
+
+        VkDescriptorPool ds_pool;
+        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL,
+                                     &ds_pool);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSetLayoutBinding dsl_binding = {};
+        dsl_binding.binding = 0;
+        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+        dsl_binding.descriptorCount = 1;
+        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+        dsl_binding.pImmutableSamplers = NULL;
+
+        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+        ds_layout_ci.sType =
+            VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        ds_layout_ci.pNext = NULL;
+        ds_layout_ci.bindingCount = 1;
+        ds_layout_ci.pBindings = &dsl_binding;
+        VkDescriptorSetLayout ds_layout;
+        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci,
+                                          NULL, &ds_layout);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSet descriptor_set;
+        VkDescriptorSetAllocateInfo alloc_info = {};
+        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+        alloc_info.descriptorSetCount = 1;
+        alloc_info.descriptorPool = ds_pool;
+        alloc_info.pSetLayouts = &ds_layout;
+        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info,
+                                       &descriptor_set);
+        ASSERT_VK_SUCCESS(err);
+
+        VkWriteDescriptorSet descriptor_write;
+        memset(&descriptor_write, 0, sizeof(descriptor_write));
+        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        descriptor_write.dstSet = descriptor_set;
+        descriptor_write.dstBinding = 0;
+        descriptor_write.descriptorCount = 1;
+        descriptor_write.descriptorType =
+            VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+        descriptor_write.pTexelBufferView = &buffer_view;
+
+        // Set pImageInfo and pBufferInfo to invalid values, which should be
+        //  ignored for descriptorType ==
+        //  VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.
+        // This will most likely produce a crash if the parameter_validation
+        // layer
+        // does not correctly ignore pImageInfo and pBufferInfo.
+        descriptor_write.pImageInfo =
+            reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
+        descriptor_write.pBufferInfo =
+            reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
+
+        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0,
+                               NULL);
+
+        m_errorMonitor->VerifyNotFound();
+
+        vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
+        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+        vkDestroyBufferView(m_device->device(), buffer_view, NULL);
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        vkFreeMemory(m_device->device(), buffer_memory, NULL);
+    }
+}
 #endif // PARAMETER_VALIDATION_TESTS
 
 #if MEM_TRACKER_TESTS
@@ -1148,6 +1886,7 @@
 
     m_errorMonitor->VerifyNotFound();
 
+    vkFreeMemory(m_device->device(), mem, NULL);
     vkDestroyBuffer(m_device->device(), buffer, NULL);
     vkDestroyImage(m_device->device(), image, NULL);
 }
@@ -1332,6 +2071,7 @@
                       (void **)&pData);
     ASSERT_VK_SUCCESS(err);
     VkMappedMemoryRange mmr = {};
+    mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
     mmr.memory = mem;
     mmr.offset = 15; // Error b/c offset less than offset of mapped mem
     m_errorMonitor->SetDesiredFailureMsg(
@@ -2094,6 +2834,7 @@
     m_errorMonitor->VerifyFound();
 
     vkDestroyImage(m_device->device(), image, NULL);
+    vkFreeMemory(m_device->device(), mem, NULL);
 }
 
 TEST_F(VkLayerTest, RebindMemory) {
@@ -2228,6 +2969,133 @@
     m_errorMonitor->VerifyNotFound();
 }
 
+#if 0
+TEST_F(VkLayerTest, LongFenceChain)
+{
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkResult err;
+
+    std::vector<VkFence> fences;
+
+    const int chainLength = 32768;
+
+    for (int i = 0; i < chainLength; i++) {
+        VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
+        VkFence fence;
+        err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
+        ASSERT_VK_SUCCESS(err);
+
+        fences.push_back(fence);
+
+        VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
+            0, nullptr, 0, nullptr };
+        err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
+        ASSERT_VK_SUCCESS(err);
+
+    }
+
+    // BOOM, stack overflow.
+    vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX);
+
+    for (auto fence : fences)
+        vkDestroyFence(m_device->device(), fence, nullptr);
+
+    m_errorMonitor->VerifyNotFound();
+}
+#endif
+
+TEST_F(VkLayerTest, CommandBufferSimultaneousUseSync)
+{
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkResult err;
+
+    // Record (empty!) command buffer that can be submitted multiple times
+    // simultaneously.
+    VkCommandBufferBeginInfo cbbi = {
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
+        VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr
+    };
+    m_commandBuffer->BeginCommandBuffer(&cbbi);
+    m_commandBuffer->EndCommandBuffer();
+
+    VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
+    VkFence fence;
+    err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
+    ASSERT_VK_SUCCESS(err);
+
+    VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 };
+    VkSemaphore s1, s2;
+    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
+    ASSERT_VK_SUCCESS(err);
+    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
+    ASSERT_VK_SUCCESS(err);
+
+    // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
+    VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
+        1, &m_commandBuffer->handle(), 1, &s1 };
+    err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
+    ASSERT_VK_SUCCESS(err);
+
+    // Submit CB again, signaling s2.
+    si.pSignalSemaphores = &s2;
+    err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
+    ASSERT_VK_SUCCESS(err);
+
+    // Wait for fence.
+    err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+    ASSERT_VK_SUCCESS(err);
+
+    // CB is still in flight from second submission, but semaphore s1 is no
+    // longer in flight. delete it.
+    vkDestroySemaphore(m_device->device(), s1, nullptr);
+
+    m_errorMonitor->VerifyNotFound();
+
+    // Force device idle and clean up remaining objects
+    vkDeviceWaitIdle(m_device->device());
+    vkDestroySemaphore(m_device->device(), s2, nullptr);
+    vkDestroyFence(m_device->device(), fence, nullptr);
+}
+
+TEST_F(VkLayerTest, FenceCreateSignaledWaitHandling)
+{
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkResult err;
+
+    // A fence created signaled
+    VkFenceCreateInfo fci1 = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT };
+    VkFence f1;
+    err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
+    ASSERT_VK_SUCCESS(err);
+
+    // A fence created not
+    VkFenceCreateInfo fci2 = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
+    VkFence f2;
+    err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
+    ASSERT_VK_SUCCESS(err);
+
+    // Submit the unsignaled fence
+    VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
+        0, nullptr, 0, nullptr };
+    err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
+
+    // Wait on both fences, with signaled first.
+    VkFence fences[] = { f1, f2 };
+    vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
+
+    // Should have both retired!
+    vkDestroyFence(m_device->device(), f1, nullptr);
+    vkDestroyFence(m_device->device(), f2, nullptr);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
 TEST_F(VkLayerTest, InvalidUsageBits)
 {
     TEST_DESCRIPTION(
@@ -2240,7 +3108,7 @@
     ASSERT_NO_FATAL_FAILURE(InitState());
     VkImageObj image(m_device);
     // Initialize image with USAGE_INPUT_ATTACHMENT
-    image.init(128, 128, VK_FORMAT_D32_SFLOAT_S8_UINT,
+    image.init(128, 128, VK_FORMAT_D24_UNORM_S8_UINT,
                VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
     ASSERT_TRUE(image.initialized());
 
@@ -2307,7 +3175,7 @@
 
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
-        "OBJ ERROR : VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT object");
+        "has not been destroyed.");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -2327,15 +3195,7 @@
         queue_info.push_back(qi);
     }
 
-    std::vector<const char *> device_layer_names;
     std::vector<const char *> device_extension_names;
-    device_layer_names.push_back("VK_LAYER_GOOGLE_threading");
-    device_layer_names.push_back("VK_LAYER_LUNARG_parameter_validation");
-    device_layer_names.push_back("VK_LAYER_LUNARG_object_tracker");
-    device_layer_names.push_back("VK_LAYER_LUNARG_core_validation");
-    device_layer_names.push_back("VK_LAYER_LUNARG_device_limits");
-    device_layer_names.push_back("VK_LAYER_LUNARG_image");
-    device_layer_names.push_back("VK_LAYER_GOOGLE_unique_objects");
 
     // The sacrificial device object
     VkDevice testDevice;
@@ -2345,8 +3205,8 @@
     device_create_info.pNext = NULL;
     device_create_info.queueCreateInfoCount = queue_info.size();
     device_create_info.pQueueCreateInfos = queue_info.data();
-    device_create_info.enabledLayerCount = device_layer_names.size();
-    device_create_info.ppEnabledLayerNames = device_layer_names.data();
+    device_create_info.enabledLayerCount = 0;
+    device_create_info.ppEnabledLayerNames = NULL;
     device_create_info.pEnabledFeatures = &features;
     err = vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
     ASSERT_VK_SUCCESS(err);
@@ -2479,7 +3339,7 @@
 
 TEST_F(VkLayerTest, CreateUnknownObject) {
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-        "Invalid VkImage Object ");
+        "Invalid Image Object ");
 
     TEST_DESCRIPTION(
         "Pass an invalid image object handle into a Vulkan API call.");
@@ -2503,7 +3363,7 @@
         "Pass in an invalid pipeline object handle into a Vulkan API call.");
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "Invalid VkPipeline Object ");
+                                         "Invalid Pipeline Object ");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -2576,12 +3436,89 @@
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 }
 
+TEST_F(VkLayerTest, BindImageInvalidMemoryType) {
+    VkResult err;
+
+    TEST_DESCRIPTION("Test validation check for an invalid memory type index "
+                     "during bind[Buffer|Image]Memory time");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // Create an image, allocate memory, set a bad typeIndex and then try to
+    // bind it
+    VkImage image;
+    VkDeviceMemory mem;
+    VkMemoryRequirements mem_reqs;
+    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
+    const int32_t tex_width = 32;
+    const int32_t tex_height = 32;
+
+    VkImageCreateInfo image_create_info = {};
+    image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_create_info.pNext = NULL;
+    image_create_info.imageType = VK_IMAGE_TYPE_2D;
+    image_create_info.format = tex_format;
+    image_create_info.extent.width = tex_width;
+    image_create_info.extent.height = tex_height;
+    image_create_info.extent.depth = 1;
+    image_create_info.mipLevels = 1;
+    image_create_info.arrayLayers = 1;
+    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+    image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+    image_create_info.flags = 0;
+
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 0;
+    mem_alloc.memoryTypeIndex = 0;
+
+    err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+    ASSERT_VK_SUCCESS(err);
+
+    vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
+    mem_alloc.allocationSize = mem_reqs.size;
+
+    // Introduce Failure, select invalid TypeIndex
+    VkPhysicalDeviceMemoryProperties memory_info;
+
+    vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
+    unsigned int i;
+    for (i = 0; i < memory_info.memoryTypeCount; i++) {
+        if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
+            mem_alloc.memoryTypeIndex = i;
+            break;
+        }
+    }
+    if (i >= memory_info.memoryTypeCount) {
+        printf("No invalid memory type index could be found; skipped.\n");
+        vkDestroyImage(m_device->device(), image, NULL);
+        return;
+    }
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "for this object type are not compatible with the memory");
+
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkBindImageMemory(m_device->device(), image, mem, 0);
+    (void)err;
+
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyImage(m_device->device(), image, NULL);
+    vkFreeMemory(m_device->device(), mem, NULL);
+}
+
 TEST_F(VkLayerTest, BindInvalidMemory) {
     VkResult err;
     bool pass;
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "Invalid VkDeviceMemory Object ");
+                                         "Invalid Device Memory Object ");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -2648,7 +3585,7 @@
     bool pass;
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "Invalid VkImage Object ");
+                                         "Invalid Image Object ");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -2715,15 +3652,1196 @@
 
 #if DRAW_STATE_TESTS
 
+TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
+    TEST_DESCRIPTION("Submit command buffer created using one queue family and "
+                     "attempt to submit them on a queue created in a different "
+                     "queue family.");
+
+    // This test is meaningless unless we have multiple queue families
+    auto queue_family_properties = m_device->phy().queue_properties();
+    if (queue_family_properties.size() < 2) {
+        return;
+    }
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " is being submitted on queue ");
+    // Get safe index of another queue family
+    uint32_t other_queue_family = (m_device->graphics_queue_node_index_ == 0) ? 1 : 0;
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    // Create a second queue using a different queue family
+    VkQueue other_queue;
+    vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
+
+    // Record an empty cmd buffer
+    VkCommandBufferBeginInfo cmdBufBeginDesc = {};
+    cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    vkBeginCommandBuffer(m_commandBuffer->handle(), &cmdBufBeginDesc);
+    vkEndCommandBuffer(m_commandBuffer->handle());
+
+    // And submit on the wrong queue
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
+
+    m_errorMonitor->VerifyFound();
+
+}
+
+TEST_F(VkLayerTest, RenderPassInitialLayoutUndefined) {
+    TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's "
+                     "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when "
+                     "the command buffer has prior knowledge of that "
+                     "attachment's layout.");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // A renderpass with one color attachment.
+    VkAttachmentDescription attachment = {
+        0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_UNDEFINED,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+    };
+
+    VkAttachmentReference att_ref = {
+        0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+    };
+
+    VkSubpassDescription subpass = {
+        0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
+        1, &att_ref, nullptr, nullptr, 0, nullptr
+    };
+
+    VkRenderPassCreateInfo rpci = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
+        0, 1, &attachment, 1, &subpass, 0, nullptr
+    };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkImageObj image(m_device);
+    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+               VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, nullptr,
+        0, image.handle(), VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM,
+        {
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY
+        },
+        {
+            VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1
+        },
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = {
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
+        0, rp, 1, &view,
+        32, 32, 1
+    };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Record a single command buffer which uses this renderpass twice. The
+    // bug is triggered at the beginning of the second renderpass, when the
+    // command buffer already has a layout recorded for the attachment.
+    VkRenderPassBeginInfo rpbi = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
+        rp, fb, { { 0, 0 } , { 32, 32 } },
+        0, nullptr
+    };
+    BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi,
+                         VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi,
+                         VK_SUBPASS_CONTENTS_INLINE);
+
+    m_errorMonitor->VerifyNotFound();
+
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    EndCommandBuffer();
+
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+}
+
+TEST_F(VkLayerTest, FramebufferBindingDestroyCommandPool) {
+    TEST_DESCRIPTION("This test should pass. Create a Framebuffer and "
+                     "command buffer, bind them together, then destroy "
+                     "command pool and framebuffer and verify there are no "
+                     "errors.");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // A renderpass with one color attachment.
+    VkAttachmentDescription attachment = {
+        0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_UNDEFINED,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+    };
+
+    VkAttachmentReference att_ref = {
+        0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+    };
+
+    VkSubpassDescription subpass = {
+        0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
+        1, &att_ref, nullptr, nullptr, 0, nullptr
+    };
+
+    VkRenderPassCreateInfo rpci = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
+        0, 1, &attachment, 1, &subpass, 0, nullptr
+    };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkImageObj image(m_device);
+    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+               VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, nullptr,
+        0, image.handle(), VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM,
+        {
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY
+        },
+        {
+            VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1
+        },
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = {
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
+        0, rp, 1, &view,
+        32, 32, 1
+    };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Explicitly create a command buffer to bind the FB to so that we can then
+    //  destroy the command pool in order to implicitly free command buffer
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr,
+                        &command_pool);
+
+    VkCommandBuffer command_buffer;
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType =
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 1;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info,
+                             &command_buffer);
+
+    // Begin our cmd buffer with renderpass using our framebuffer
+    VkRenderPassBeginInfo rpbi = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
+        rp, fb, { { 0, 0 } , { 32, 32 } },
+        0, nullptr
+    };
+    VkCommandBufferBeginInfo begin_info{};
+    begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    vkBeginCommandBuffer(command_buffer, &begin_info);
+
+    vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdEndRenderPass(command_buffer);
+    vkEndCommandBuffer(command_buffer);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+    // Destroy command pool to implicitly free command buffer
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkLayerTest, RenderPassSubpassZeroTransitionsApplied) {
+    TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout "
+                     "transitions for the first subpass");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // A renderpass with one color attachment.
+    VkAttachmentDescription attachment = {
+        0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_UNDEFINED,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+    };
+
+    VkAttachmentReference att_ref = {
+        0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+    };
+
+    VkSubpassDescription subpass = {
+        0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
+        1, &att_ref, nullptr, nullptr, 0, nullptr
+    };
+
+    VkSubpassDependency dep = {
+        0, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_DEPENDENCY_BY_REGION_BIT
+    };
+
+    VkRenderPassCreateInfo rpci = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
+        0, 1, &attachment, 1, &subpass, 1, &dep
+    };
+
+    VkResult err;
+    VkRenderPass rp;
+    err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkImageObj image(m_device);
+    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+               VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, nullptr,
+        0, image.handle(), VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM,
+        {
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY,
+            VK_COMPONENT_SWIZZLE_IDENTITY
+        },
+        {
+            VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1
+        },
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = {
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
+        0, rp, 1, &view,
+        32, 32, 1
+    };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Record a single command buffer which issues a pipeline barrier w/
+    // image memory barrier for the attachment. This detects the previously
+    // missing tracking of the subpass layout by throwing a validation error
+    // if it doesn't occur.
+    VkRenderPassBeginInfo rpbi = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
+        rp, fb, { { 0, 0 }, { 32, 32 } },
+        0, nullptr
+    };
+    BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi,
+                         VK_SUBPASS_CONTENTS_INLINE);
+
+    VkImageMemoryBarrier imb = {
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, nullptr,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
+        image.handle(),
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
+    };
+    vkCmdPipelineBarrier(m_commandBuffer->handle(),
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_DEPENDENCY_BY_REGION_BIT,
+                         0, nullptr, 0, nullptr, 1, &imb);
+
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    m_errorMonitor->VerifyNotFound();
+    EndCommandBuffer();
+
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+}
+
+TEST_F(VkLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
+    TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image "
+                     "is used as a depth/stencil framebuffer attachment, the "
+                     "aspectMask is ignored and both depth and stencil image "
+                     "subresources are used.");
+
+    VkFormatProperties format_properties;
+    vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT,
+                                        &format_properties);
+    if (!(format_properties.optimalTilingFeatures &
+          VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
+        return;
+    }
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkAttachmentDescription attachment = {
+        0,
+        VK_FORMAT_D32_SFLOAT_S8_UINT,
+        VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
+
+    VkAttachmentReference att_ref = {
+        0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
+
+    VkSubpassDescription subpass = {0,       VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                    0,       nullptr,
+                                    0,       nullptr,
+                                    nullptr, &att_ref,
+                                    0,       nullptr};
+
+    VkSubpassDependency dep = {0,
+                               0,
+                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+                               VK_DEPENDENCY_BY_REGION_BIT};
+
+    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+                                   nullptr,
+                                   0,
+                                   1,
+                                   &attachment,
+                                   1,
+                                   &subpass,
+                                   1,
+                                   &dep};
+
+    VkResult err;
+    VkRenderPass rp;
+    err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    VkImageObj image(m_device);
+    image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT,
+                         0x26, // usage
+                         VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+    image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+        nullptr,
+        0,
+        image.handle(),
+        VK_IMAGE_VIEW_TYPE_2D,
+        VK_FORMAT_D32_SFLOAT_S8_UINT,
+        {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
+         VK_COMPONENT_SWIZZLE_A},
+        {0x2, 0, 1, 0, 1},
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+                                   nullptr,
+                                   0,
+                                   rp,
+                                   1,
+                                   &view,
+                                   32,
+                                   32,
+                                   1};
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+                                  nullptr,
+                                  rp,
+                                  fb,
+                                  {{0, 0}, {32, 32}},
+                                  0,
+                                  nullptr};
+    BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi,
+                         VK_SUBPASS_CONTENTS_INLINE);
+
+    VkImageMemoryBarrier imb = {};
+    imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+    imb.pNext = nullptr;
+    imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+    imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    imb.srcQueueFamilyIndex = 0;
+    imb.dstQueueFamilyIndex = 0;
+    imb.image = image.handle();
+    imb.subresourceRange.aspectMask = 0x6;
+    imb.subresourceRange.baseMipLevel = 0;
+    imb.subresourceRange.levelCount = 0x1;
+    imb.subresourceRange.baseArrayLayer = 0;
+    imb.subresourceRange.layerCount = 0x1;
+
+    vkCmdPipelineBarrier(m_commandBuffer->handle(),
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
+                         &imb);
+
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    EndCommandBuffer();
+    QueueCommandBuffer(false);
+    m_errorMonitor->VerifyNotFound();
+
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+}
+
+TEST_F(VkLayerTest, RenderPassTransitionsAttachmentUnused) {
+    TEST_DESCRIPTION("Ensure that layout transitions work correctly without "
+                     "errors, when an attachment reference is "
+                     "VK_ATTACHMENT_UNUSED");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // A renderpass with no attachments
+    VkAttachmentReference att_ref = {
+        VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+    };
+
+    VkSubpassDescription subpass = {
+        0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
+        1, &att_ref, nullptr, nullptr, 0, nullptr
+    };
+
+    VkRenderPassCreateInfo rpci = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
+        0, 0, nullptr, 1, &subpass, 0, nullptr
+    };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkFramebufferCreateInfo fci = {
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
+        0, rp, 0, nullptr,
+        32, 32, 1
+    };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Record a command buffer which just begins and ends the renderpass. The
+    // bug manifests in BeginRenderPass.
+    VkRenderPassBeginInfo rpbi = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
+        rp, fb, { { 0, 0 }, { 32, 32 } },
+        0, nullptr
+    };
+    BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi,
+                         VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    m_errorMonitor->VerifyNotFound();
+    EndCommandBuffer();
+
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+}
+
+// This is a positive test. No errors are expected.
+TEST_F(VkLayerTest, StencilLoadOp) {
+    TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to "
+                     "CLEAR. stencil[Load|Store]Op used to be ignored.");
+    VkResult result = VK_SUCCESS;
+    VkImageFormatProperties formatProps;
+    vkGetPhysicalDeviceImageFormatProperties(
+        gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D,
+        VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
+                                     VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+        0, &formatProps);
+    if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
+        return;
+    }
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT;
+    m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
+                         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
+                             VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+    VkAttachmentDescription att = {};
+    VkAttachmentReference ref = {};
+    att.format = depth_stencil_fmt;
+    att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+    att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
+    att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+    VkClearValue clear;
+    clear.depthStencil.depth = 1.0;
+    clear.depthStencil.stencil = 0;
+    ref.attachment = 0;
+    ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+    VkSubpassDescription subpass = {};
+    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+    subpass.flags = 0;
+    subpass.inputAttachmentCount = 0;
+    subpass.pInputAttachments = NULL;
+    subpass.colorAttachmentCount = 0;
+    subpass.pColorAttachments = NULL;
+    subpass.pResolveAttachments = NULL;
+    subpass.pDepthStencilAttachment = &ref;
+    subpass.preserveAttachmentCount = 0;
+    subpass.pPreserveAttachments = NULL;
+
+    VkRenderPass rp;
+    VkRenderPassCreateInfo rp_info = {};
+    rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    rp_info.attachmentCount = 1;
+    rp_info.pAttachments = &att;
+    rp_info.subpassCount = 1;
+    rp_info.pSubpasses = &subpass;
+    result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
+    ASSERT_VK_SUCCESS(result);
+
+    VkImageView *depthView = m_depthStencil->BindInfo();
+    VkFramebufferCreateInfo fb_info = {};
+    fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+    fb_info.pNext = NULL;
+    fb_info.renderPass = rp;
+    fb_info.attachmentCount = 1;
+    fb_info.pAttachments = depthView;
+    fb_info.width = 100;
+    fb_info.height = 100;
+    fb_info.layers = 1;
+    VkFramebuffer fb;
+    result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+    ASSERT_VK_SUCCESS(result);
+
+
+    VkRenderPassBeginInfo rpbinfo = {};
+    rpbinfo.clearValueCount = 1;
+    rpbinfo.pClearValues = &clear;
+    rpbinfo.pNext = NULL;
+    rpbinfo.renderPass = rp;
+    rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+    rpbinfo.renderArea.extent.width = 100;
+    rpbinfo.renderArea.extent.height = 100;
+    rpbinfo.renderArea.offset.x = 0;
+    rpbinfo.renderArea.offset.y = 0;
+    rpbinfo.framebuffer = fb;
+
+    VkFence fence = {};
+    VkFenceCreateInfo fence_ci = {};
+    fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fence_ci.pNext = nullptr;
+    fence_ci.flags = 0;
+    result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
+    ASSERT_VK_SUCCESS(result);
+
+
+    m_commandBuffer->BeginCommandBuffer();
+    m_commandBuffer->BeginRenderPass(rpbinfo);
+    m_commandBuffer->EndRenderPass();
+    m_commandBuffer->EndCommandBuffer();
+    m_commandBuffer->QueueCommandBuffer(fence);
+
+    VkImageObj destImage(m_device);
+    destImage.init(100, 100, depth_stencil_fmt,
+                   VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
+                       VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+                   VK_IMAGE_TILING_OPTIMAL, 0);
+    VkImageMemoryBarrier barrier = {};
+    VkImageSubresourceRange range;
+    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+    barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT |
+                            VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT |
+                            VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+    barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+    barrier.image = m_depthStencil->handle();
+    range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+    range.baseMipLevel = 0;
+    range.levelCount = 1;
+    range.baseArrayLayer = 0;
+    range.layerCount = 1;
+    barrier.subresourceRange = range;
+    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+    VkCommandBufferObj cmdbuf(m_device, m_commandPool);
+    cmdbuf.BeginCommandBuffer();
+    cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                           VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0,
+                           nullptr, 1, &barrier);
+    barrier.srcAccessMask = 0;
+    barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+    barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+    barrier.image = destImage.handle();
+    barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT |
+                            VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                           VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0,
+                           nullptr, 1, &barrier);
+    VkImageCopy cregion;
+    cregion.srcSubresource.aspectMask =
+        VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+    cregion.srcSubresource.mipLevel = 0;
+    cregion.srcSubresource.baseArrayLayer = 0;
+    cregion.srcSubresource.layerCount = 1;
+    cregion.srcOffset.x = 0;
+    cregion.srcOffset.y = 0;
+    cregion.srcOffset.z = 0;
+    cregion.dstSubresource.aspectMask =
+        VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+    cregion.dstSubresource.mipLevel = 0;
+    cregion.dstSubresource.baseArrayLayer = 0;
+    cregion.dstSubresource.layerCount = 1;
+    cregion.dstOffset.x = 0;
+    cregion.dstOffset.y = 0;
+    cregion.dstOffset.z = 0;
+    cregion.extent.width = 100;
+    cregion.extent.height = 100;
+    cregion.extent.depth = 1;
+    cmdbuf.CopyImage(m_depthStencil->handle(),
+                     VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
+                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
+    cmdbuf.EndCommandBuffer();
+
+    VkSubmitInfo submit_info;
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.pNext = NULL;
+    submit_info.waitSemaphoreCount = 0;
+    submit_info.pWaitSemaphores = NULL;
+    submit_info.pWaitDstStageMask = NULL;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &cmdbuf.handle();
+    submit_info.signalSemaphoreCount = 0;
+    submit_info.pSignalSemaphores = NULL;
+
+    m_errorMonitor->ExpectSuccess();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    m_errorMonitor->VerifyNotFound();
+
+    vkQueueWaitIdle(m_device->m_queue);
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+}
+
+TEST_F(VkLayerTest, UnusedPreserveAttachment) {
+    TEST_DESCRIPTION("Create a framebuffer where a subpass has a preserve "
+                     "attachment reference of VK_ATTACHMENT_UNUSED");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "must not be VK_ATTACHMENT_UNUSED");
+
+    VkAttachmentReference color_attach = {};
+    color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
+    color_attach.attachment = 0;
+    uint32_t preserve_attachment = VK_ATTACHMENT_UNUSED;
+    VkSubpassDescription subpass = {};
+    subpass.colorAttachmentCount = 1;
+    subpass.pColorAttachments = &color_attach;
+    subpass.preserveAttachmentCount = 1;
+    subpass.pPreserveAttachments = &preserve_attachment;
+
+    VkRenderPassCreateInfo rpci = {};
+    rpci.subpassCount = 1;
+    rpci.pSubpasses = &subpass;
+    rpci.attachmentCount = 1;
+    VkAttachmentDescription attach_desc = {};
+    attach_desc.format = VK_FORMAT_UNDEFINED;
+    rpci.pAttachments = &attach_desc;
+    rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    VkRenderPass rp;
+    VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+
+    m_errorMonitor->VerifyFound();
+
+    if (result == VK_SUCCESS) {
+        vkDestroyRenderPass(m_device->device(), rp, NULL);
+    }
+}
+
+TEST_F(VkLayerTest, CreateRenderPassResolveRequiresColorMsaa) {
+    TEST_DESCRIPTION("Ensure that CreateRenderPass produces a validation error "
+                     "when the source of a subpass multisample resolve "
+                     "does not have multiple samples.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "Subpass 0 requests multisample resolve from attachment 0 which has "
+        "VK_SAMPLE_COUNT_1_BIT");
+
+    VkAttachmentDescription attachments[] = {
+        {
+            0, VK_FORMAT_R8G8B8A8_UNORM,
+            VK_SAMPLE_COUNT_1_BIT,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+        },
+        {
+            0, VK_FORMAT_R8G8B8A8_UNORM,
+            VK_SAMPLE_COUNT_1_BIT,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+        },
+    };
+
+    VkAttachmentReference color = {
+        0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+    };
+
+    VkAttachmentReference resolve = {
+        0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+    };
+
+    VkSubpassDescription subpass = {
+        0, VK_PIPELINE_BIND_POINT_GRAPHICS,
+        0, nullptr,
+        1, &color,
+        &resolve,
+        nullptr,
+        0, nullptr
+    };
+
+    VkRenderPassCreateInfo rpci = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
+        0, 2, attachments, 1, &subpass, 0, nullptr
+    };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+
+    m_errorMonitor->VerifyFound();
+
+    if (err == VK_SUCCESS)
+        vkDestroyRenderPass(m_device->device(), rp, nullptr);
+}
+
+TEST_F(VkLayerTest, CreateRenderPassResolveRequiresSingleSampleDest) {
+    TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
+                     "when a subpass multisample resolve operation is "
+                     "requested, and the destination of that resolve has "
+                     "multiple samples.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "Subpass 0 requests multisample resolve into attachment 1, which "
+        "must have VK_SAMPLE_COUNT_1_BIT but has VK_SAMPLE_COUNT_4_BIT");
+
+    VkAttachmentDescription attachments[] = {
+        {
+            0, VK_FORMAT_R8G8B8A8_UNORM,
+            VK_SAMPLE_COUNT_4_BIT,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+        },
+        {
+            0, VK_FORMAT_R8G8B8A8_UNORM,
+            VK_SAMPLE_COUNT_4_BIT,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+        },
+    };
+
+    VkAttachmentReference color = {
+        0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+    };
+
+    VkAttachmentReference resolve = {
+        1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+    };
+
+    VkSubpassDescription subpass = {
+        0, VK_PIPELINE_BIND_POINT_GRAPHICS,
+        0, nullptr,
+        1, &color,
+        &resolve,
+        nullptr,
+        0, nullptr
+    };
+
+    VkRenderPassCreateInfo rpci = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
+        0, 2, attachments, 1, &subpass, 0, nullptr
+    };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+
+    m_errorMonitor->VerifyFound();
+
+    if (err == VK_SUCCESS)
+        vkDestroyRenderPass(m_device->device(), rp, nullptr);
+}
+
+TEST_F(VkLayerTest, CreateRenderPassSubpassSampleCountConsistency) {
+    TEST_DESCRIPTION("Ensure CreateRenderPass produces a validation error "
+                     "when the color and depth attachments used by a subpass "
+                     "have inconsistent sample counts");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "Subpass 0 attempts to render to attachments with inconsistent sample counts");
+
+    VkAttachmentDescription attachments[] = {
+        {
+            0, VK_FORMAT_R8G8B8A8_UNORM,
+            VK_SAMPLE_COUNT_1_BIT,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+        },
+        {
+            0, VK_FORMAT_R8G8B8A8_UNORM,
+            VK_SAMPLE_COUNT_4_BIT,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+        },
+    };
+
+    VkAttachmentReference color[] = {
+        {
+            0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        },
+        {
+            1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        },
+    };
+
+    VkSubpassDescription subpass = {
+        0, VK_PIPELINE_BIND_POINT_GRAPHICS,
+        0, nullptr,
+        2, color,
+        nullptr,
+        nullptr,
+        0, nullptr
+    };
+
+    VkRenderPassCreateInfo rpci = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
+        0, 2, attachments, 1, &subpass, 0, nullptr
+    };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+
+    m_errorMonitor->VerifyFound();
+
+    if (err == VK_SUCCESS)
+        vkDestroyRenderPass(m_device->device(), rp, nullptr);
+}
+
+TEST_F(VkLayerTest, FramebufferCreateErrors) {
+    TEST_DESCRIPTION("Hit errors when attempting to create a framebuffer :\n"
+                     " 1. Mismatch between fb & renderPass attachmentCount\n"
+                     " 2. Use a color image as depthStencil attachment\n"
+                     " 3. Mismatch fb & renderPass attachment formats\n"
+                     " 4. Mismatch fb & renderPass attachment #samples\n"
+                     " 5. FB attachment w/ non-1 mip-levels\n"
+                     " 6. FB attachment where dimensions don't match\n"
+                     " 7. FB attachment w/o identity swizzle\n"
+                     " 8. FB dimensions exceed physical device limits\n");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of 2 "
+        "does not match attachmentCount of 1 of ");
+
+    // Create a renderPass with a single color attachment
+    VkAttachmentReference attach = {};
+    attach.layout = VK_IMAGE_LAYOUT_GENERAL;
+    VkSubpassDescription subpass = {};
+    subpass.pColorAttachments = &attach;
+    VkRenderPassCreateInfo rpci = {};
+    rpci.subpassCount = 1;
+    rpci.pSubpasses = &subpass;
+    rpci.attachmentCount = 1;
+    VkAttachmentDescription attach_desc = {};
+    attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
+    attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
+    rpci.pAttachments = &attach_desc;
+    rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    VkImageView ivs[2];
+    ivs[0] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
+    ivs[1] = m_renderTargets[0]->targetView(VK_FORMAT_B8G8R8A8_UNORM);
+    VkFramebufferCreateInfo fb_info = {};
+    fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+    fb_info.pNext = NULL;
+    fb_info.renderPass = rp;
+    // Set mis-matching attachmentCount
+    fb_info.attachmentCount = 2;
+    fb_info.pAttachments = ivs;
+    fb_info.width = 100;
+    fb_info.height = 100;
+    fb_info.layers = 1;
+
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+
+    m_errorMonitor->VerifyFound();
+    if (err == VK_SUCCESS) {
+        vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    }
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
+
+    // Create a renderPass with a depth-stencil attachment created with
+    // IMAGE_USAGE_COLOR_ATTACHMENT
+    // Add our color attachment to pDepthStencilAttachment
+    subpass.pDepthStencilAttachment = &attach;
+    subpass.pColorAttachments = NULL;
+    VkRenderPass rp_ds;
+    err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp_ds);
+    ASSERT_VK_SUCCESS(err);
+    // Set correct attachment count, but attachment has COLOR usage bit set
+    fb_info.attachmentCount = 1;
+    fb_info.renderPass = rp_ds;
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " conflicts with the image's IMAGE_USAGE flags ");
+    err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+
+    m_errorMonitor->VerifyFound();
+    if (err == VK_SUCCESS) {
+        vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    }
+    vkDestroyRenderPass(m_device->device(), rp_ds, NULL);
+
+    // Create new renderpass with alternate attachment format from fb
+    attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
+    subpass.pDepthStencilAttachment = NULL;
+    subpass.pColorAttachments = &attach;
+    err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // Cause error due to mis-matched formats between rp & fb
+    //  rp attachment 0 now has RGBA8 but corresponding fb attach is BGRA8
+    fb_info.renderPass = rp;
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " has format of VK_FORMAT_B8G8R8A8_UNORM that does not match ");
+    err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+
+    m_errorMonitor->VerifyFound();
+    if (err == VK_SUCCESS) {
+        vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    }
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
+
+    // Create new renderpass with alternate sample count from fb
+    attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM;
+    attach_desc.samples = VK_SAMPLE_COUNT_4_BIT;
+    err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // Cause error due to mis-matched sample count between rp & fb
+    fb_info.renderPass = rp;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " has VK_SAMPLE_COUNT_1_BIT samples "
+                                         "that do not match the "
+                                         "VK_SAMPLE_COUNT_4_BIT ");
+    err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+
+    m_errorMonitor->VerifyFound();
+    if (err == VK_SUCCESS) {
+        vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    }
+
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
+
+    // Create a custom imageView with non-1 mip levels
+    VkImageObj image(m_device);
+    image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM,
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageView view;
+    VkImageViewCreateInfo ivci = {};
+    ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    ivci.image = image.handle();
+    ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
+    ivci.subresourceRange.layerCount = 1;
+    ivci.subresourceRange.baseMipLevel = 0;
+    // Set level count 2 (only 1 is allowed for FB attachment)
+    ivci.subresourceRange.levelCount = 2;
+    ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
+    ASSERT_VK_SUCCESS(err);
+    // Re-create renderpass to have matching sample count
+    attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
+    err = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    fb_info.renderPass = rp;
+    fb_info.pAttachments = &view;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " has mip levelCount of 2 but only ");
+    err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+
+    m_errorMonitor->VerifyFound();
+    if (err == VK_SUCCESS) {
+        vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    }
+    vkDestroyImageView(m_device->device(), view, NULL);
+    // Update view to original color buffer and grow FB dimensions too big
+    fb_info.pAttachments = ivs;
+    fb_info.height = 1024;
+    fb_info.width = 1024;
+    fb_info.layers = 2;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " Attachment dimensions must be at "
+                                         "least as large. ");
+    err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+
+    m_errorMonitor->VerifyFound();
+    if (err == VK_SUCCESS) {
+        vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    }
+    // Create view attachment with non-identity swizzle
+    ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    ivci.image = image.handle();
+    ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    ivci.format = VK_FORMAT_B8G8R8A8_UNORM;
+    ivci.subresourceRange.layerCount = 1;
+    ivci.subresourceRange.baseMipLevel = 0;
+    ivci.subresourceRange.levelCount = 1;
+    ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    ivci.components.r = VK_COMPONENT_SWIZZLE_G;
+    ivci.components.g = VK_COMPONENT_SWIZZLE_R;
+    ivci.components.b = VK_COMPONENT_SWIZZLE_A;
+    ivci.components.a = VK_COMPONENT_SWIZZLE_B;
+    err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    fb_info.pAttachments = &view;
+    fb_info.height = 100;
+    fb_info.width = 100;
+    fb_info.layers = 1;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " has non-identy swizzle. All "
+                                         "framebuffer attachments must have "
+                                         "been created with the identity "
+                                         "swizzle. ");
+    err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+
+    m_errorMonitor->VerifyFound();
+    if (err == VK_SUCCESS) {
+        vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    }
+    vkDestroyImageView(m_device->device(), view, NULL);
+    // Request fb that exceeds max dimensions
+    // reset attachment to color attachment
+    fb_info.pAttachments = ivs;
+    fb_info.width = m_device->props.limits.maxFramebufferWidth + 1;
+    fb_info.height = m_device->props.limits.maxFramebufferHeight + 1;
+    fb_info.layers = m_device->props.limits.maxFramebufferLayers + 1;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " Requested VkFramebufferCreateInfo "
+                                         "dimensions exceed physical device "
+                                         "limits. ");
+    err = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+
+    m_errorMonitor->VerifyFound();
+    if (err == VK_SUCCESS) {
+        vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    }
+
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
+}
+
 // This is a positive test.  No errors should be generated.
 TEST_F(VkLayerTest, WaitEventThenSet) {
     TEST_DESCRIPTION(
         "Wait on a event then set it after the wait has been submitted.");
 
-    if ((m_device->queue_props.empty()) ||
-        (m_device->queue_props[0].queueCount < 2))
-        return;
-
     m_errorMonitor->ExpectSuccess();
 
     VkEvent event;
@@ -2751,7 +4869,7 @@
 
     VkQueue queue = VK_NULL_HANDLE;
     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_,
-                     1, &queue);
+                     0, &queue);
 
     {
         VkCommandBufferBeginInfo begin_info{};
@@ -2785,6 +4903,137 @@
     m_errorMonitor->VerifyNotFound();
 }
 // This is a positive test.  No errors should be generated.
+TEST_F(VkLayerTest, QueryAndCopySecondaryCommandBuffers) {
+    TEST_DESCRIPTION(
+        "Issue a query on a secondary command buffery and copy it on a primary.");
+
+    if ((m_device->queue_props.empty()) ||
+        (m_device->queue_props[0].queueCount < 2))
+        return;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkQueryPool query_pool;
+    VkQueryPoolCreateInfo query_pool_create_info{};
+    query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
+    query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
+    query_pool_create_info.queryCount = 1;
+    vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr,
+                      &query_pool);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr,
+                        &command_pool);
+
+    VkCommandBuffer command_buffer;
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType =
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 1;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info,
+                             &command_buffer);
+
+    VkCommandBuffer secondary_command_buffer;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info,
+                             &secondary_command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_,
+                     1, &queue);
+
+    uint32_t qfi = 0;
+    VkBufferCreateInfo buff_create_info = {};
+    buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buff_create_info.size = 1024;
+    buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+    buff_create_info.queueFamilyIndexCount = 1;
+    buff_create_info.pQueueFamilyIndices = &qfi;
+
+    VkResult err;
+    VkBuffer buffer;
+    err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 1024;
+    mem_alloc.memoryTypeIndex = 0;
+
+    VkMemoryRequirements memReqs;
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
+    bool pass =
+        m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
+    if (!pass) {
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        return;
+    }
+
+    VkDeviceMemory mem;
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    VkCommandBufferInheritanceInfo hinfo = {};
+    hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+    hinfo.renderPass = VK_NULL_HANDLE;
+    hinfo.subpass = 0;
+    hinfo.framebuffer = VK_NULL_HANDLE;
+    hinfo.occlusionQueryEnable = VK_FALSE;
+    hinfo.queryFlags = 0;
+    hinfo.pipelineStatistics = 0;
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        begin_info.pInheritanceInfo = &hinfo;
+        vkBeginCommandBuffer(secondary_command_buffer, &begin_info);
+
+        vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1);
+        vkCmdWriteTimestamp(secondary_command_buffer,
+                            VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
+
+        vkEndCommandBuffer(secondary_command_buffer);
+
+        begin_info.pInheritanceInfo = nullptr;
+        vkBeginCommandBuffer(command_buffer, &begin_info);
+
+        vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer);
+        vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer,
+                                  0, 0, 0);
+
+        vkEndCommandBuffer(command_buffer);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer;
+        submit_info.signalSemaphoreCount = 0;
+        submit_info.pSignalSemaphores = nullptr;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+
+    vkQueueWaitIdle(queue);
+
+    vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkFreeMemory(m_device->device(), mem, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+// This is a positive test.  No errors should be generated.
 TEST_F(VkLayerTest, QueryAndCopyMultipleCommandBuffers) {
     TEST_DESCRIPTION(
         "Issue a query and copy from it on a second command buffer.");
@@ -2891,6 +5140,8 @@
     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
     vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkFreeMemory(m_device->device(), mem, NULL);
 
     m_errorMonitor->VerifyNotFound();
 }
@@ -2899,10 +5150,6 @@
     TEST_DESCRIPTION(
         "Reset an event then set it after the reset has been submitted.");
 
-    if ((m_device->queue_props.empty()) ||
-        (m_device->queue_props[0].queueCount < 2))
-        return;
-
     m_errorMonitor->ExpectSuccess();
 
     VkEvent event;
@@ -2930,7 +5177,7 @@
 
     VkQueue queue = VK_NULL_HANDLE;
     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_,
-                     1, &queue);
+                     0, &queue);
 
     {
         VkCommandBufferBeginInfo begin_info{};
@@ -2971,6 +5218,83 @@
 }
 
 // This is a positive test.  No errors should be generated.
+TEST_F(VkLayerTest, TwoFencesThreeFrames) {
+    TEST_DESCRIPTION("Two command buffers with two separate fences are each "
+                     "run through a Submit & WaitForFences cycle 3 times. This "
+                     "previously revealed a bug so running this positive test "
+                     "to prevent a regression.");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_,
+                     0, &queue);
+
+    static const uint32_t NUM_OBJECTS = 2;
+    static const uint32_t NUM_FRAMES = 3;
+    VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
+    VkFence fences[NUM_OBJECTS] = {};
+
+    VkCommandPool cmd_pool;
+    VkCommandPoolCreateInfo cmd_pool_ci = {};
+    cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci,
+                                       nullptr, &cmd_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkCommandBufferAllocateInfo cmd_buf_info = {};
+    cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    cmd_buf_info.commandPool = cmd_pool;
+    cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    cmd_buf_info.commandBufferCount = 1;
+
+    VkFenceCreateInfo fence_ci = {};
+    fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fence_ci.pNext = nullptr;
+    fence_ci.flags = 0;
+
+    for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
+        err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info,
+                                       &cmd_buffers[i]);
+        ASSERT_VK_SUCCESS(err);
+        err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
+        ASSERT_VK_SUCCESS(err);
+    }
+
+    for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
+        for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
+            // Create empty cmd buffer
+            VkCommandBufferBeginInfo cmdBufBeginDesc = {};
+            cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+
+            err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
+            ASSERT_VK_SUCCESS(err);
+            err = vkEndCommandBuffer(cmd_buffers[obj]);
+            ASSERT_VK_SUCCESS(err);
+
+            VkSubmitInfo submit_info = {};
+            submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+            submit_info.commandBufferCount = 1;
+            submit_info.pCommandBuffers = &cmd_buffers[obj];
+            // Submit cmd buffer and wait for fence
+            err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
+            ASSERT_VK_SUCCESS(err);
+            err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE,
+                                  UINT64_MAX);
+            ASSERT_VK_SUCCESS(err);
+            err = vkResetFences(m_device->device(), 1, &fences[obj]);
+            ASSERT_VK_SUCCESS(err);
+        }
+    }
+    m_errorMonitor->VerifyNotFound();
+    vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
+    for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
+        vkDestroyFence(m_device->device(), fences[i], nullptr);
+    }
+}
+// This is a positive test.  No errors should be generated.
 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
 
     TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
@@ -3305,6 +5629,88 @@
     m_errorMonitor->VerifyNotFound();
 }
 
+#if 0
+TEST_F(VkLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
+    if ((m_device->queue_props.empty()) ||
+        (m_device->queue_props[0].queueCount < 2)) {
+        printf("Test requires two queues, skipping\n");
+        return;
+    }
+
+    VkResult err;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkQueue q0 = m_device->m_queue;
+    VkQueue q1 = nullptr;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
+    ASSERT_NE(q1, nullptr);
+
+    // An (empty) command buffer. We must have work in the first submission --
+    // the layer treats unfenced work differently from fenced work.
+    VkCommandPoolCreateInfo cpci = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0 };
+    VkCommandPool pool;
+    err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
+    ASSERT_VK_SUCCESS(err);
+    VkCommandBufferAllocateInfo cbai = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr,
+        pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1
+    };
+    VkCommandBuffer cb;
+    err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
+    ASSERT_VK_SUCCESS(err);
+    VkCommandBufferBeginInfo cbbi = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
+        0, nullptr
+    };
+    err = vkBeginCommandBuffer(cb, &cbbi);
+    ASSERT_VK_SUCCESS(err);
+    err = vkEndCommandBuffer(cb);
+    ASSERT_VK_SUCCESS(err);
+
+    // A semaphore
+    VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 };
+    VkSemaphore s;
+    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
+    ASSERT_VK_SUCCESS(err);
+
+    // First submission, to q0
+    VkSubmitInfo s0 = {
+        VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr,
+        0, nullptr, nullptr,
+        1, &cb,
+        1, &s
+    };
+
+    err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
+    ASSERT_VK_SUCCESS(err);
+
+    // Second submission, to q1, waiting on s
+    VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is.
+    VkSubmitInfo s1 = {
+        VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr,
+        1, &s, &waitmask,
+        0, nullptr,
+        0, nullptr
+    };
+
+    err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
+    ASSERT_VK_SUCCESS(err);
+
+    // Wait for q0 idle
+    err = vkQueueWaitIdle(q0);
+    ASSERT_VK_SUCCESS(err);
+
+    // Command buffer should have been completed (it was on q0); reset the pool.
+    vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
+
+    m_errorMonitor->VerifyNotFound();
+
+    // Force device completely idle and clean up resources
+    vkDeviceWaitIdle(m_device->device());
+    vkDestroyCommandPool(m_device->device(), pool, nullptr);
+    vkDestroySemaphore(m_device->device(), s, nullptr);
+}
+#endif
+
 // This is a positive test.  No errors should be generated.
 TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
 
@@ -3616,7 +6022,9 @@
 
     vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
 
-    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+    VkResult err =
+        vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+    ASSERT_VK_SUCCESS(err);
 
     vkDestroyFence(m_device->device(), fence, nullptr);
     vkFreeCommandBuffers(m_device->device(), command_pool, 2,
@@ -3829,19 +6237,29 @@
     vkFreeCommandBuffers(m_device->device(), command_pool, 2,
                          &command_buffer[0]);
     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
 
     m_errorMonitor->VerifyNotFound();
 }
 
-TEST_F(VkLayerTest, DynamicStatesNotBound) {
+TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
     TEST_DESCRIPTION(
-        "Run a series of simple draw calls to validate all the different "
-        "failure cases that can occur when dynamic state is required but not "
-        "correctly bound."
-        "Here are the different dynamic state cases verified by this test:\n"
-        "-Line Width\n-Depth Bias\n-Viewport State\n-Scissor State\n-Blend "
-        "State\n-Depth Bounds\n-Stencil Read Mask\n-Stencil Write "
-        "Mask\n-Stencil Reference");
+        "Run a simple draw calls to validate failure when Depth Bias dynamic "
+        "state is required but not correctly bound.");
+
+    // Dynamic depth bias
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "Dynamic depth bias state not set for this command buffer");
+    VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
+                   BsoFailDepthBias);
+    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
+    TEST_DESCRIPTION(
+        "Run a simple draw calls to validate failure when Line Width dynamic "
+        "state is required but not correctly bound.");
 
     // Dynamic line width
     m_errorMonitor->SetDesiredFailureMsg(
@@ -3850,13 +6268,13 @@
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
                    BsoFailLineWidth);
     m_errorMonitor->VerifyFound();
-    // Dynamic depth bias
-    m_errorMonitor->SetDesiredFailureMsg(
-        VK_DEBUG_REPORT_ERROR_BIT_EXT,
-        "Dynamic depth bias state not set for this command buffer");
-    VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
-                   BsoFailDepthBias);
-    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, DynamicViewportNotBound) {
+    TEST_DESCRIPTION(
+        "Run a simple draw calls to validate failure when Viewport dynamic "
+        "state is required but not correctly bound.");
+
     // Dynamic viewport state
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -3864,6 +6282,13 @@
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
                    BsoFailViewport);
     m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, DynamicScissorNotBound) {
+    TEST_DESCRIPTION(
+        "Run a simple draw calls to validate failure when Scissor dynamic "
+        "state is required but not correctly bound.");
+
     // Dynamic scissor state
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -3871,13 +6296,42 @@
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
                    BsoFailScissor);
     m_errorMonitor->VerifyFound();
-    // Dynamic blend state
+}
+
+TEST_F(VkLayerTest, DynamiBlendConstantsNotBound) {
+    TEST_DESCRIPTION(
+        "Run a simple draw calls to validate failure when Blend Constants "
+        "dynamic state is required but not correctly bound.");
+    // Dynamic blend constant state
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "Dynamic blend constants state not set for this command buffer");
+    VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
+                   BsoFailBlend);
+    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
+    TEST_DESCRIPTION(
+        "Run a simple draw calls to validate failure when Depth Bounds dynamic "
+        "state is required but not correctly bound.");
+    if (!m_device->phy().features().depthBounds) {
+        printf("Device does not support depthBounds test; skipped.\n");
+        return;
+    }
+    // Dynamic depth bounds
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "Dynamic depth bounds state not set for this command buffer");
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
                    BsoFailDepthBounds);
     m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
+    TEST_DESCRIPTION(
+        "Run a simple draw calls to validate failure when Stencil Read dynamic "
+        "state is required but not correctly bound.");
     // Dynamic stencil read mask
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -3885,6 +6339,12 @@
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
                    BsoFailStencilReadMask);
     m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
+    TEST_DESCRIPTION(
+        "Run a simple draw calls to validate failure when Stencil Write dynamic"
+        " state is required but not correctly bound.");
     // Dynamic stencil write mask
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -3892,6 +6352,12 @@
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
                    BsoFailStencilWriteMask);
     m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
+    TEST_DESCRIPTION(
+        "Run a simple draw calls to validate failure when Stencil Ref dynamic "
+        "state is required but not correctly bound.");
     // Dynamic stencil reference
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -3901,19 +6367,22 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
-    vk_testing::Fence testFence;
+TEST_F(VkLayerTest, IndexBufferNotBound) {
+    TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "Index buffer object not bound to this command buffer when Indexed ");
+    VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText,
+                   BsoFailIndexBuffer);
+    m_errorMonitor->VerifyFound();
+}
 
+TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has "
         "been submitted");
 
-    VkFenceCreateInfo fenceInfo = {};
-    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    fenceInfo.pNext = NULL;
-    fenceInfo.flags = 0;
-
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitViewport());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -3925,8 +6394,6 @@
                                      m_stencil_clear_color, NULL);
     EndCommandBuffer();
 
-    testFence.init(*m_device, fenceInfo);
-
     // Bypass framework since it does the waits automatically
     VkResult err = VK_SUCCESS;
     VkSubmitInfo submit_info;
@@ -3940,12 +6407,12 @@
     submit_info.signalSemaphoreCount = 0;
     submit_info.pSignalSemaphores = NULL;
 
-    err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
+    err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
     ASSERT_VK_SUCCESS(err);
 
     // Cause validation error by re-submitting cmd buffer that should only be
     // submitted once
-    err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
+    err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
 
     m_errorMonitor->VerifyFound();
 }
@@ -4083,7 +6550,7 @@
     // Attempt to clear Descriptor Pool with bad object.
     // ObjectTracker should catch this.
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "Invalid VkDescriptorPool Object 0xbaad6001");
+                                         "Invalid Descriptor Pool Object 0xbaad6001");
     uint64_t fake_pool_handle = 0xbaad6001;
     VkDescriptorPool bad_pool = reinterpret_cast<VkDescriptorPool &>(fake_pool_handle);
     vkResetDescriptorPool(device(), bad_pool, 0);
@@ -4100,7 +6567,7 @@
     VkDescriptorSet bad_set = reinterpret_cast<VkDescriptorSet &>(fake_set_handle);
     VkResult err;
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "Invalid VkDescriptorSet Object 0xbaad6001");
+                                         "Invalid Descriptor Set Object 0xbaad6001");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -4144,7 +6611,7 @@
     uint64_t fake_layout_handle = 0xbaad6001;
     VkDescriptorSetLayout bad_layout = reinterpret_cast<VkDescriptorSetLayout &>(fake_layout_handle);
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "Invalid VkDescriptorSetLayout Object 0xbaad6001");
+                                         "Invalid Descriptor Set Layout Object 0xbaad6001");
 
     VkPipelineLayout pipeline_layout;
     VkPipelineLayoutCreateInfo plci = {};
@@ -4157,6 +6624,622 @@
     m_errorMonitor->VerifyFound();
 }
 
+TEST_F(VkLayerTest, WriteDescriptorSetIntegrityCheck) {
+    TEST_DESCRIPTION("This test verifies some requirements of chapter 13.2.3 of the Vulkan Spec "
+                     "1) A uniform buffer update must have a valid buffer index."
+                     "2) When using an array of descriptors in a single WriteDescriptor,"
+                     "     the descriptor types and stageflags must all be the same."
+                     "3) Immutable Sampler state must match across descriptors");
+
+    const char *invalid_BufferInfo_ErrorMessage =
+            "vkUpdateDescriptorSets: if pDescriptorWrites[0].descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "
+            "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or "
+            "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pDescriptorWrites[0].pBufferInfo must not be NULL";
+    const char *stateFlag_ErrorMessage =
+            "Attempting write update to descriptor set ";
+    const char *immutable_ErrorMessage =
+            "Attempting write update to descriptor set ";
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_BufferInfo_ErrorMessage);
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkDescriptorPoolSize ds_type_count[4] = {};
+    ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    ds_type_count[0].descriptorCount = 1;
+    ds_type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    ds_type_count[1].descriptorCount = 1;
+    ds_type_count[2].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    ds_type_count[2].descriptorCount = 1;
+    ds_type_count[3].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
+    ds_type_count[3].descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = sizeof(ds_type_count) / sizeof(VkDescriptorPoolSize);
+    ds_pool_ci.pPoolSizes = ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding layout_binding[3] = {};
+    layout_binding[0].binding = 0;
+    layout_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    layout_binding[0].descriptorCount = 1;
+    layout_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
+    layout_binding[0].pImmutableSamplers = NULL;
+
+    layout_binding[1].binding = 1;
+    layout_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
+    layout_binding[1].descriptorCount = 1;
+    layout_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    layout_binding[1].pImmutableSamplers = NULL;
+
+    VkSamplerCreateInfo sampler_ci = {};
+    sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+    sampler_ci.pNext = NULL;
+    sampler_ci.magFilter = VK_FILTER_NEAREST;
+    sampler_ci.minFilter = VK_FILTER_NEAREST;
+    sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+    sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.mipLodBias = 1.0;
+    sampler_ci.anisotropyEnable = VK_FALSE;
+    sampler_ci.maxAnisotropy = 1;
+    sampler_ci.compareEnable = VK_FALSE;
+    sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
+    sampler_ci.minLod = 1.0;
+    sampler_ci.maxLod = 1.0;
+    sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
+    sampler_ci.unnormalizedCoordinates = VK_FALSE;
+    VkSampler sampler;
+
+    err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
+    ASSERT_VK_SUCCESS(err);
+
+    layout_binding[2].binding = 2;
+    layout_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
+    layout_binding[2].descriptorCount = 1;
+    layout_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    layout_binding[2].pImmutableSamplers = static_cast<VkSampler *>(&sampler);
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.bindingCount = sizeof(layout_binding) / sizeof(VkDescriptorSetLayoutBinding);
+    ds_layout_ci.pBindings = layout_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    VkDescriptorSet descriptorSet;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pNext = NULL;
+    pipeline_layout_ci.setLayoutCount = 1;
+    pipeline_layout_ci.pSetLayouts = &ds_layout;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstSet = descriptorSet;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+
+    // 1) The uniform buffer is intentionally invalid here
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+    m_errorMonitor->VerifyFound();
+
+    // Create a buffer to update the descriptor with
+    uint32_t qfi = 0;
+    VkBufferCreateInfo buffCI = {};
+    buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buffCI.size = 1024;
+    buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buffCI.queueFamilyIndexCount = 1;
+    buffCI.pQueueFamilyIndices = &qfi;
+
+    VkBuffer dyub;
+    err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
+    ASSERT_VK_SUCCESS(err);
+    VkDescriptorBufferInfo buffInfo = {};
+    buffInfo.buffer = dyub;
+    buffInfo.offset = 0;
+    buffInfo.range = 1024;
+
+    descriptor_write.pBufferInfo = &buffInfo;
+    descriptor_write.descriptorCount = 2;
+
+    // 2) The stateFlags don't match between the first and second descriptor
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, stateFlag_ErrorMessage);
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+    m_errorMonitor->VerifyFound();
+
+    // 3) The second descriptor has a null_ptr pImmutableSamplers and
+    // the third descriptor contains an immutable sampler
+    descriptor_write.dstBinding = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
+
+
+    // Make pImageInfo index non-null to avoid complaints of it missing
+    VkDescriptorImageInfo imageInfo = {};
+    imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    descriptor_write.pImageInfo = &imageInfo;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, immutable_ErrorMessage);
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyBuffer(m_device->device(), dyub, NULL);
+    vkDestroySampler(m_device->device(), sampler, NULL);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
+TEST_F(VkLayerTest, InvalidCmdBufferBufferDestroyed) {
+    TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
+                     "due to a buffer dependency being destroyed.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkImageObj image(m_device);
+    image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM,
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                   VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+               VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkBuffer buffer;
+    VkDeviceMemory mem;
+    VkMemoryRequirements mem_reqs;
+
+    VkBufferCreateInfo buf_info = {};
+    buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buf_info.size = 256;
+    buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
+
+    VkMemoryAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    alloc_info.allocationSize = 256;
+    bool pass = false;
+    pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
+                                           VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+    if (!pass) {
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        return;
+    }
+    err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    VkBufferImageCopy region = {};
+    region.bufferRowLength = 128;
+    region.bufferImageHeight = 128;
+    region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+
+    region.imageSubresource.layerCount = 1;
+    region.imageExtent.height = 4;
+    region.imageExtent.width = 4;
+    region.imageExtent.depth = 1;
+    m_commandBuffer->BeginCommandBuffer();
+    vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer,
+                           image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                           1, &region);
+    m_commandBuffer->EndCommandBuffer();
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " that is invalid because bound buffer ");
+    // Destroy buffer dependency prior to submit to cause ERROR
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+
+    m_errorMonitor->VerifyFound();
+    vkFreeMemory(m_device->handle(), mem, NULL);
+}
+
+TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
+    TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
+                     "due to an image dependency being destroyed.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkImage image;
+    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
+    VkImageCreateInfo image_create_info = {};
+    image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_create_info.pNext = NULL;
+    image_create_info.imageType = VK_IMAGE_TYPE_2D;
+    image_create_info.format = tex_format;
+    image_create_info.extent.width = 32;
+    image_create_info.extent.height = 32;
+    image_create_info.extent.depth = 1;
+    image_create_info.mipLevels = 1;
+    image_create_info.arrayLayers = 1;
+    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+    image_create_info.usage =
+        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+    image_create_info.flags = 0;
+    VkResult err =
+        vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+    ASSERT_VK_SUCCESS(err);
+    // Have to bind memory to image before recording cmd in cmd buffer using it
+    VkMemoryRequirements mem_reqs;
+    VkDeviceMemory image_mem;
+    bool pass;
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.memoryTypeIndex = 0;
+    vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
+    mem_alloc.allocationSize = mem_reqs.size;
+    pass =
+        m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
+    ASSERT_TRUE(pass);
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    m_commandBuffer->BeginCommandBuffer();
+    VkClearColorValue ccv;
+    ccv.float32[0] = 1.0f;
+    ccv.float32[1] = 1.0f;
+    ccv.float32[2] = 1.0f;
+    ccv.float32[3] = 1.0f;
+    VkImageSubresourceRange isr = {};
+    isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    isr.baseArrayLayer = 0;
+    isr.baseMipLevel = 0;
+    isr.layerCount = 1;
+    isr.levelCount = 1;
+    vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image,
+                         VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
+    m_commandBuffer->EndCommandBuffer();
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound image ");
+    // Destroy image dependency prior to submit to cause ERROR
+    vkDestroyImage(m_device->device(), image, NULL);
+
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+
+    m_errorMonitor->VerifyFound();
+    vkFreeMemory(m_device->device(), image_mem, nullptr);
+}
+
+TEST_F(VkLayerTest, ImageMemoryNotBound) {
+    TEST_DESCRIPTION(
+        "Attempt to draw with an image which has not had memory bound to it.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkImage image;
+    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
+    VkImageCreateInfo image_create_info = {};
+    image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_create_info.pNext = NULL;
+    image_create_info.imageType = VK_IMAGE_TYPE_2D;
+    image_create_info.format = tex_format;
+    image_create_info.extent.width = 32;
+    image_create_info.extent.height = 32;
+    image_create_info.extent.depth = 1;
+    image_create_info.mipLevels = 1;
+    image_create_info.arrayLayers = 1;
+    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+    image_create_info.usage =
+        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+    image_create_info.flags = 0;
+    VkResult err =
+        vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+    ASSERT_VK_SUCCESS(err);
+    // Have to bind memory to image before recording cmd in cmd buffer using it
+    VkMemoryRequirements mem_reqs;
+    VkDeviceMemory image_mem;
+    bool pass;
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.memoryTypeIndex = 0;
+    vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
+    mem_alloc.allocationSize = mem_reqs.size;
+    pass =
+        m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
+    ASSERT_TRUE(pass);
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
+    ASSERT_VK_SUCCESS(err);
+
+    // Introduce error, do not call vkBindImageMemory(m_device->device(), image,
+    // image_mem, 0);
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "used without first calling vkBindImageMemory");
+
+    m_commandBuffer->BeginCommandBuffer();
+    VkClearColorValue ccv;
+    ccv.float32[0] = 1.0f;
+    ccv.float32[1] = 1.0f;
+    ccv.float32[2] = 1.0f;
+    ccv.float32[3] = 1.0f;
+    VkImageSubresourceRange isr = {};
+    isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    isr.baseArrayLayer = 0;
+    isr.baseMipLevel = 0;
+    isr.layerCount = 1;
+    isr.levelCount = 1;
+    vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), image,
+                         VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
+    m_commandBuffer->EndCommandBuffer();
+
+    m_errorMonitor->VerifyFound();
+    vkDestroyImage(m_device->device(), image, NULL);
+    vkFreeMemory(m_device->device(), image_mem, nullptr);
+}
+
+TEST_F(VkLayerTest, BufferMemoryNotBound) {
+    TEST_DESCRIPTION(
+        "Attempt to copy from a buffer which has not had memory bound to it.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkImageObj image(m_device);
+    image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM,
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                   VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+               VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkBuffer buffer;
+    VkDeviceMemory mem;
+    VkMemoryRequirements mem_reqs;
+
+    VkBufferCreateInfo buf_info = {};
+    buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buf_info.size = 256;
+    buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
+
+    VkMemoryAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    alloc_info.allocationSize = 256;
+    bool pass = false;
+    pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
+                                           VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+    if (!pass) {
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        return;
+    }
+    err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+
+    // Introduce failure by not calling vkBindBufferMemory(m_device->device(),
+    // buffer, mem, 0);
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "used without first calling vkBindBufferMemory");
+    VkBufferImageCopy region = {};
+    region.bufferRowLength = 128;
+    region.bufferImageHeight = 128;
+    region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+
+    region.imageSubresource.layerCount = 1;
+    region.imageExtent.height = 4;
+    region.imageExtent.width = 4;
+    region.imageExtent.depth = 1;
+    m_commandBuffer->BeginCommandBuffer();
+    vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer,
+                           image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                           1, &region);
+    m_commandBuffer->EndCommandBuffer();
+
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkFreeMemory(m_device->handle(), mem, NULL);
+}
+
+TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
+    TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
+                     "due to an event dependency being destroyed.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkEvent event;
+    VkEventCreateInfo evci = {};
+    evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+    VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
+    ASSERT_VK_SUCCESS(result);
+
+    m_commandBuffer->BeginCommandBuffer();
+    vkCmdSetEvent(m_commandBuffer->GetBufferHandle(), event,
+                  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
+    m_commandBuffer->EndCommandBuffer();
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound event ");
+    // Destroy event dependency prior to submit to cause ERROR
+    vkDestroyEvent(m_device->device(), event, NULL);
+
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+
+    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
+    TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
+                     "due to a query pool dependency being destroyed.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkQueryPool query_pool;
+    VkQueryPoolCreateInfo qpci{};
+    qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
+    qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
+    qpci.queryCount = 1;
+    VkResult result =
+        vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
+    ASSERT_VK_SUCCESS(result);
+
+    m_commandBuffer->BeginCommandBuffer();
+    vkCmdResetQueryPool(m_commandBuffer->GetBufferHandle(), query_pool, 0, 1);
+    m_commandBuffer->EndCommandBuffer();
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " that is invalid because bound query pool ");
+    // Destroy query pool dependency prior to submit to cause ERROR
+    vkDestroyQueryPool(m_device->device(), query_pool, NULL);
+
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+
+    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, InvalidCmdBufferPipelineDestroyed) {
+    TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
+                     "due to a pipeline dependency being destroyed.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkResult err;
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
+                                 &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineViewportStateCreateInfo vp_state_ci = {};
+    vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+    vp_state_ci.viewportCount = 1;
+    VkViewport vp = {};           // Just need dummy vp to point to
+    vp_state_ci.pViewports = &vp;
+    vp_state_ci.scissorCount = 1;
+    VkRect2D scissors = {}; // Dummy scissors to point to
+    vp_state_ci.pScissors = &scissors;
+    // No dynamic state
+    VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
+    dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+
+    VkPipelineShaderStageCreateInfo shaderStages[2];
+    memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
+
+    VkShaderObj vs(m_device, bindStateVertShaderText,
+                   VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, bindStateFragShaderText,
+                   VK_SHADER_STAGE_FRAGMENT_BIT,
+                   this); // We shouldn't need a fragment shader
+                          // but add it to be able to run on more devices
+    shaderStages[0] = vs.GetStageCreateInfo();
+    shaderStages[1] = fs.GetStageCreateInfo();
+
+    VkPipelineVertexInputStateCreateInfo vi_ci = {};
+    vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+
+    VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
+    ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+    ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+    VkPipelineRasterizationStateCreateInfo rs_ci = {};
+    rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+
+    VkPipelineColorBlendAttachmentState att = {};
+    att.blendEnable = VK_FALSE;
+    att.colorWriteMask = 0xf;
+
+    VkPipelineColorBlendStateCreateInfo cb_ci = {};
+    cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+    cb_ci.attachmentCount = 1;
+    cb_ci.pAttachments = &att;
+
+    VkGraphicsPipelineCreateInfo gp_ci = {};
+    gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+    gp_ci.stageCount = 2;
+    gp_ci.pStages = shaderStages;
+    gp_ci.pVertexInputState = &vi_ci;
+    gp_ci.pInputAssemblyState = &ia_ci;
+    gp_ci.pViewportState = &vp_state_ci;
+    gp_ci.pRasterizationState = &rs_ci;
+    gp_ci.pColorBlendState = &cb_ci;
+    gp_ci.pDynamicState = &dyn_state_ci;
+    gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
+    gp_ci.layout = pipeline_layout;
+    gp_ci.renderPass = renderPass();
+
+    VkPipelineCacheCreateInfo pc_ci = {};
+    pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+
+    VkPipeline pipeline;
+    VkPipelineCache pipelineCache;
+    err =
+        vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
+                                    &gp_ci, NULL, &pipeline);
+    ASSERT_VK_SUCCESS(err);
+
+    m_commandBuffer->BeginCommandBuffer();
+    vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
+                      VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+    m_commandBuffer->EndCommandBuffer();
+    // Now destroy pipeline in order to cause error when submitting
+    vkDestroyPipeline(m_device->device(), pipeline, nullptr);
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " that is invalid because bound pipeline ");
+
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+
+    m_errorMonitor->VerifyFound();
+    vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+}
+
 TEST_F(VkLayerTest, InvalidPipeline) {
     // Attempt to bind an invalid Pipeline to a valid Command Buffer
     // ObjectTracker should catch this.
@@ -4165,18 +7248,17 @@
     uint64_t fake_pipeline_handle = 0xbaad6001;
     VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "Invalid VkPipeline Object 0xbaad6001");
+                                         "Invalid Pipeline Object 0xbaad6001");
     ASSERT_NO_FATAL_FAILURE(InitState());
     BeginCommandBuffer();
     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
                       VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
     m_errorMonitor->VerifyFound();
-
     // Now issue a draw call with no pipeline bound
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "At Draw/Dispatch time no valid VkPipeline is bound!");
-    ASSERT_NO_FATAL_FAILURE(InitState());
+
     BeginCommandBuffer();
     Draw(1, 0, 0, 0);
     m_errorMonitor->VerifyFound();
@@ -4184,7 +7266,6 @@
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "At Draw/Dispatch time no valid VkPipeline is bound!");
-    ASSERT_NO_FATAL_FAILURE(InitState());
     BeginCommandBuffer();
     vkCmdDispatch(m_commandBuffer->GetBufferHandle(), 0, 0, 0);
     m_errorMonitor->VerifyFound();
@@ -4353,6 +7434,45 @@
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 }
 
+TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
+    TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has"
+                     " no memory bound to it.");
+
+    VkResult err;
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "used without first calling vkBindBufferMemory");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // Create a buffer with no bound memory and then attempt to create
+    // a buffer view.
+    VkBufferCreateInfo buff_ci = {};
+    buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buff_ci.size = 256;
+    buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    VkBuffer buffer;
+    err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+
+    VkBufferViewCreateInfo buff_view_ci = {};
+    buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+    buff_view_ci.buffer = buffer;
+    buff_view_ci.format = VK_FORMAT_R8_UNORM;
+    buff_view_ci.range = VK_WHOLE_SIZE;
+    VkBufferView buff_view;
+    err =
+        vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
+
+    m_errorMonitor->VerifyFound();
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    // If last error is success, it still created the view, so delete it.
+    if (err == VK_SUCCESS) {
+        vkDestroyBufferView(m_device->device(), buff_view, NULL);
+    }
+}
+
 TEST_F(VkLayerTest, InvalidDynamicOffsetCases) {
     // Create a descriptorSet w/ dynamic descriptor and then hit 3 offset error
     // cases:
@@ -4533,6 +7653,98 @@
     vkFreeMemory(m_device->device(), mem, NULL);
 
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
+TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
+    TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer "
+                     "that doesn't have memory bound");
+    VkResult err;
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " used without first calling vkBindBufferMemory.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitViewport());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkDescriptorPoolSize ds_type_count = {};
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
+    ds_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.pNext = NULL;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    err =
+        vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding dsl_binding = {};
+    dsl_binding.binding = 0;
+    dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
+    dsl_binding.descriptorCount = 1;
+    dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+    dsl_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &dsl_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
+                                      &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSet descriptorSet;
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info,
+                                   &descriptorSet);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create a buffer to update the descriptor with
+    uint32_t qfi = 0;
+    VkBufferCreateInfo buffCI = {};
+    buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buffCI.size = 1024;
+    buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buffCI.queueFamilyIndexCount = 1;
+    buffCI.pQueueFamilyIndices = &qfi;
+
+    VkBuffer dyub;
+    err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
+    ASSERT_VK_SUCCESS(err);
+
+    // Attempt to update descriptor without binding memory to it
+    VkDescriptorBufferInfo buffInfo = {};
+    buffInfo.buffer = dyub;
+    buffInfo.offset = 0;
+    buffInfo.range = 1024;
+
+    VkWriteDescriptorSet descriptor_write;
+    memset(&descriptor_write, 0, sizeof(descriptor_write));
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstSet = descriptorSet;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
+    descriptor_write.pBufferInfo = &buffInfo;
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyBuffer(m_device->device(), dyub, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 }
 
@@ -4881,6 +8093,22 @@
     ASSERT_NO_FATAL_FAILURE(InitViewport());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
 
+    const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
+    VkImageTiling tiling;
+    VkFormatProperties format_properties;
+    vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
+    if (format_properties.linearTilingFeatures &
+        VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
+        tiling = VK_IMAGE_TILING_LINEAR;
+    } else if (format_properties.optimalTilingFeatures &
+               VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
+        tiling = VK_IMAGE_TILING_OPTIMAL;
+    } else {
+        printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; "
+               "skipped.\n");
+        return;
+    }
+
     static const uint32_t NUM_DESCRIPTOR_TYPES = 5;
     VkDescriptorPoolSize ds_type_count[NUM_DESCRIPTOR_TYPES] = {};
     ds_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@@ -5052,7 +8280,6 @@
         buffInfo[i].range = 1024;
     }
     VkImage image;
-    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
     const int32_t tex_width = 32;
     const int32_t tex_height = 32;
     VkImageCreateInfo image_create_info = {};
@@ -5066,8 +8293,9 @@
     image_create_info.mipLevels = 1;
     image_create_info.arrayLayers = 1;
     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
-    image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
-    image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+    image_create_info.tiling = tiling;
+    image_create_info.usage =
+        VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
     image_create_info.flags = 0;
     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
     ASSERT_VK_SUCCESS(err);
@@ -5181,7 +8409,7 @@
     // verify_set_layout_compatibility fail cases:
     // 1. invalid VkPipelineLayout (layout) passed into vkCmdBindDescriptorSets
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         " due to: invalid VkPipelineLayout ");
+                                         "Invalid Pipeline Layout Object ");
     vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(),
                             VK_PIPELINE_BIND_POINT_GRAPHICS,
                             (VkPipelineLayout)((size_t)0xbaadb1be), 0, 1,
@@ -5253,6 +8481,11 @@
                             pipe_layout_fs_only, 0, 1, &ds0_fs_only, 0, NULL);
     m_errorMonitor->VerifyFound();
 
+    // Now that we're done actively using the pipelineLayout that gfx pipeline
+    //  was created with, we should be able to delete it. Do that now to verify
+    //  that validation obeys pipelineLayout lifetime
+    vkDestroyPipelineLayout(m_device->device(), pipe_layout_fs_only, NULL);
+
     // Cause draw-time errors due to PSO incompatibilities
     // 1. Error due to not binding required set (we actually use same code as
     // above to disturb set0)
@@ -5281,7 +8514,6 @@
     m_errorMonitor->VerifyFound();
 
     // Remaining clean-up
-    vkDestroyPipelineLayout(m_device->device(), pipe_layout_fs_only, NULL);
     for (uint32_t i = 0; i < NUM_LAYOUTS; ++i) {
         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout[i], NULL);
     }
@@ -5291,6 +8523,9 @@
     vkDestroyBuffer(m_device->device(), dyub, NULL);
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+    vkFreeMemory(m_device->device(), imageMem, NULL);
+    vkDestroyImage(m_device->device(), image, NULL);
+    vkDestroyImageView(m_device->device(), view, NULL);
 }
 
 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
@@ -5897,6 +9132,12 @@
         "Gfx Pipeline viewportCount is 1, but pViewports is NULL. ");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
+
+    if (!m_device->phy().features().multiViewport) {
+        printf("Device does not support multiple viewports/scissors; skipped.\n");
+        return;
+    }
+
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
 
     VkDescriptorPoolSize ds_type_count = {};
@@ -6036,8 +9277,7 @@
     // pViewports
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
-        "Dynamic scissorCount from vkCmdSetScissor() is 2, but PSO "
-        "scissorCount is 1. These counts must match.");
+        "Dynamic scissor(s) 0 are used by PSO, ");
 
     VkViewport vp = {}; // Just need dummy vp to point to
     vp_state_ci.pViewports = &vp;
@@ -6047,9 +9287,9 @@
     BeginCommandBuffer();
     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
                       VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
-    VkRect2D scissors[2] = {}; // don't care about data
+    VkRect2D scissors[1] = {}; // don't care about data
     // Count of 2 doesn't match PSO count of 1
-    vkCmdSetScissor(m_commandBuffer->GetBufferHandle(), 0, 2, scissors);
+    vkCmdSetScissor(m_commandBuffer->GetBufferHandle(), 1, 1, scissors);
     Draw(1, 0, 0, 0);
 
     m_errorMonitor->VerifyFound();
@@ -6058,6 +9298,7 @@
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+    vkDestroyPipeline(m_device->device(), pipeline, NULL);
 }
 // Create PSO w/o non-zero scissorCount but no scissor data
 // Then run second test where dynamic viewportCount doesn't match PSO
@@ -6070,6 +9311,12 @@
         "Gfx Pipeline scissorCount is 1, but pScissors is NULL. ");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
+
+    if (!m_device->phy().features().multiViewport) {
+        printf("Device does not support multiple viewports/scissors; skipped.\n");
+        return;
+    }
+
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
 
     VkDescriptorPoolSize ds_type_count = {};
@@ -6210,8 +9457,7 @@
     // pViewports
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
-        "Dynamic viewportCount from vkCmdSetViewport() is 2, but PSO "
-        "viewportCount is 1. These counts must match.");
+        "Dynamic viewport(s) 0 are used by PSO, ");
 
     VkRect2D sc = {}; // Just need dummy vp to point to
     vp_state_ci.pScissors = &sc;
@@ -6221,9 +9467,9 @@
     BeginCommandBuffer();
     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
                       VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
-    VkViewport viewports[2] = {}; // don't care about data
+    VkViewport viewports[1] = {}; // don't care about data
     // Count of 2 doesn't match PSO count of 1
-    vkCmdSetViewport(m_commandBuffer->GetBufferHandle(), 0, 2, viewports);
+    vkCmdSetViewport(m_commandBuffer->GetBufferHandle(), 1, 1, viewports);
     Draw(1, 0, 0, 0);
 
     m_errorMonitor->VerifyFound();
@@ -6232,6 +9478,7 @@
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+    vkDestroyPipeline(m_device->device(), pipeline, NULL);
 }
 
 TEST_F(VkLayerTest, PSOLineWidthInvalid) {
@@ -6378,6 +9625,7 @@
                                     &gp_ci, NULL, &pipeline);
 
     m_errorMonitor->VerifyFound();
+    vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "Attempt to set lineWidth to 65536");
@@ -6392,6 +9640,7 @@
                                     &gp_ci, NULL, &pipeline);
 
     m_errorMonitor->VerifyFound();
+    vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "Attempt to set lineWidth to -1");
@@ -6425,6 +9674,7 @@
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+    vkDestroyPipeline(m_device->device(), pipeline, NULL);
 }
 
 TEST_F(VkLayerTest, NullRenderPass) {
@@ -6457,16 +9707,94 @@
     BeginCommandBuffer();
     // Just create a dummy Renderpass that's non-NULL so we can get to the
     // proper error
+    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo,
+                         VK_SUBPASS_CONTENTS_INLINE);
+
+    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    BeginCommandBuffer(); // framework implicitly begins the renderpass.
+    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // end implicit.
+
+    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo,
+                         VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
+    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
+    m_errorMonitor->VerifyNotFound();
+    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo,
+                         VK_SUBPASS_CONTENTS_INLINE);
+    m_errorMonitor->VerifyNotFound();
+    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
+    m_errorMonitor->VerifyNotFound();
+
+    m_commandBuffer->EndCommandBuffer();
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkLayerTest, RenderPassClearOpMismatch) {
+    TEST_DESCRIPTION("Begin a renderPass where clearValueCount is less than"
+                     "the number of renderPass attachments that use loadOp"
+                     "VK_ATTACHMENT_LOAD_OP_CLEAR.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    // Create a renderPass with a single attachment that uses loadOp CLEAR
+    VkAttachmentReference attach = {};
+    attach.layout = VK_IMAGE_LAYOUT_GENERAL;
+    VkSubpassDescription subpass = {};
+    subpass.inputAttachmentCount = 1;
+    subpass.pInputAttachments = &attach;
+    VkRenderPassCreateInfo rpci = {};
+    rpci.subpassCount = 1;
+    rpci.pSubpasses = &subpass;
+    rpci.attachmentCount = 1;
+    VkAttachmentDescription attach_desc = {};
+    attach_desc.format = VK_FORMAT_UNDEFINED;
+    // Set loadOp to CLEAR
+    attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    rpci.pAttachments = &attach_desc;
+    rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    VkRenderPass rp;
+    vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+
+    VkCommandBufferInheritanceInfo hinfo = {};
+    hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+    hinfo.renderPass = VK_NULL_HANDLE;
+    hinfo.subpass = 0;
+    hinfo.framebuffer = VK_NULL_HANDLE;
+    hinfo.occlusionQueryEnable = VK_FALSE;
+    hinfo.queryFlags = 0;
+    hinfo.pipelineStatistics = 0;
+    VkCommandBufferBeginInfo info = {};
+    info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    info.pInheritanceInfo = &hinfo;
+
+    vkBeginCommandBuffer(m_commandBuffer->handle(), &info);
     VkRenderPassBeginInfo rp_begin = {};
     rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
     rp_begin.pNext = NULL;
     rp_begin.renderPass = renderPass();
     rp_begin.framebuffer = framebuffer();
+    rp_begin.clearValueCount = 0; // Should be 1
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " has a clearValueCount of 0 but "
+                                         "there must be at least 1 entries in "
+                                         "pClearValues array to account for ");
 
     vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rp_begin,
                          VK_SUBPASS_CONTENTS_INLINE);
 
     m_errorMonitor->VerifyFound();
+
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
 }
 
 TEST_F(VkLayerTest, EndCommandBufferWithinRenderPass) {
@@ -6533,7 +9861,7 @@
 
     VkDeviceSize dstOffset = 0;
     VkDeviceSize dataSize = 1024;
-    const uint32_t *pData = NULL;
+    const void *pData = NULL;
 
     vkCmdUpdateBuffer(m_commandBuffer->GetBufferHandle(), dstBuffer.handle(),
                       dstOffset, dataSize, pData);
@@ -6628,7 +9956,7 @@
     VkResult err;
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "vkCmdClearAttachments: This call "
+                                         "vkCmdClearAttachments(): This call "
                                          "must be issued inside an active "
                                          "render pass");
 
@@ -6797,20 +10125,90 @@
                          VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1,
                          &buf_barrier, 0, nullptr);
     m_errorMonitor->VerifyFound();
-    buf_barrier.size = VK_WHOLE_SIZE;
 
+    // Now exercise barrier aspect bit errors, first DS
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "Image is a depth and stencil format and thus must "
-        "have both VK_IMAGE_ASPECT_DEPTH_BIT and "
+        "have either one or both of VK_IMAGE_ASPECT_DEPTH_BIT and "
         "VK_IMAGE_ASPECT_STENCIL_BIT set.");
     VkDepthStencilObj ds_image(m_device);
     ds_image.Init(m_device, 128, 128, VK_FORMAT_D24_UNORM_S8_UINT);
     ASSERT_TRUE(ds_image.initialized());
-    img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-    img_barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    img_barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
     img_barrier.image = ds_image.handle();
-    // Leave aspectMask at COLOR on purpose
+    // Use of COLOR aspect on DS image is error
+    img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(),
+                         VK_PIPELINE_STAGE_HOST_BIT,
+                         VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 0,
+                         nullptr, 1, &img_barrier);
+    m_errorMonitor->VerifyFound();
+    // Now test depth-only
+    VkFormatProperties format_props;
+
+    vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(),
+                                        VK_FORMAT_D16_UNORM, &format_props);
+    if (format_props.optimalTilingFeatures &
+        VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+        m_errorMonitor->SetDesiredFailureMsg(
+            VK_DEBUG_REPORT_ERROR_BIT_EXT,
+            "Image is a depth-only format and thus must "
+            "have VK_IMAGE_ASPECT_DEPTH_BIT set.");
+        VkDepthStencilObj d_image(m_device);
+        d_image.Init(m_device, 128, 128, VK_FORMAT_D16_UNORM);
+        ASSERT_TRUE(d_image.initialized());
+        img_barrier.oldLayout =
+            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+        img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+        img_barrier.image = d_image.handle();
+        // Use of COLOR aspect on depth image is error
+        img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(),
+                             VK_PIPELINE_STAGE_HOST_BIT,
+                             VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
+                             0, nullptr, 1, &img_barrier);
+        m_errorMonitor->VerifyFound();
+    }
+    vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(),
+                                        VK_FORMAT_S8_UINT, &format_props);
+    if (format_props.optimalTilingFeatures &
+        VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+        // Now test stencil-only
+        m_errorMonitor->SetDesiredFailureMsg(
+            VK_DEBUG_REPORT_ERROR_BIT_EXT,
+            "Image is a stencil-only format and thus must "
+            "have VK_IMAGE_ASPECT_STENCIL_BIT set.");
+        VkDepthStencilObj s_image(m_device);
+        s_image.Init(m_device, 128, 128, VK_FORMAT_S8_UINT);
+        ASSERT_TRUE(s_image.initialized());
+        img_barrier.oldLayout =
+            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+        img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+        img_barrier.image = s_image.handle();
+        // Use of COLOR aspect on depth image is error
+        img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+        vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(),
+                             VK_PIPELINE_STAGE_HOST_BIT,
+                             VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
+                             0, nullptr, 1, &img_barrier);
+        m_errorMonitor->VerifyFound();
+    }
+    // Finally test color
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT, "Image is a color format and thus must "
+                                       "have VK_IMAGE_ASPECT_COLOR_BIT set.");
+    VkImageObj c_image(m_device);
+    c_image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM,
+                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL,
+                 0);
+    ASSERT_TRUE(c_image.initialized());
+    img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+    img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+    img_barrier.image = c_image.handle();
+    // Set aspect to depth (non-color)
+    img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
     vkCmdPipelineBarrier(m_commandBuffer->GetBufferHandle(),
                          VK_PIPELINE_STAGE_HOST_BIT,
                          VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 0,
@@ -6877,11 +10275,12 @@
     vkCreateBuffer(m_device->device(), &buffCI, NULL, &ib);
 
     m_errorMonitor->VerifyFound();
+    vkDestroyBuffer(m_device->device(), ib, NULL);
 }
 
 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
-    // Attempt vkCmdExecuteCommands w/ a primary cmd buffer (should only be
-    // secondary)
+    TEST_DESCRIPTION("Attempt vkCmdExecuteCommands w/ a primary cmd buffer"
+                     " (should only be secondary)");
 
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -6891,13 +10290,456 @@
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
 
     BeginCommandBuffer();
-    // ASSERT_VK_SUCCESS(err);
+
     VkCommandBuffer primCB = m_commandBuffer->GetBufferHandle();
     vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &primCB);
 
     m_errorMonitor->VerifyFound();
 }
 
+TEST_F(VkLayerTest, DSUsageBitsErrors) {
+    TEST_DESCRIPTION("Attempt to update descriptor sets for images and buffers "
+                     "that do not have correct usage bits sets.");
+    VkResult err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkDescriptorPoolSize ds_type_count[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
+    for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
+        ds_type_count[i].type = VkDescriptorType(i);
+        ds_type_count[i].descriptorCount = 1;
+    }
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.pNext = NULL;
+    ds_pool_ci.maxSets = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
+    ds_pool_ci.poolSizeCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
+    ds_pool_ci.pPoolSizes = ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    err =
+        vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create 10 layouts where each has a single descriptor of different type
+    VkDescriptorSetLayoutBinding dsl_binding[VK_DESCRIPTOR_TYPE_RANGE_SIZE] =
+        {};
+    for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
+        dsl_binding[i].binding = 0;
+        dsl_binding[i].descriptorType = VkDescriptorType(i);
+        dsl_binding[i].descriptorCount = 1;
+        dsl_binding[i].stageFlags = VK_SHADER_STAGE_ALL;
+        dsl_binding[i].pImmutableSamplers = NULL;
+    }
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = 1;
+    VkDescriptorSetLayout ds_layouts[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
+    for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
+        ds_layout_ci.pBindings = dsl_binding + i;
+        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci,
+                                          NULL, ds_layouts + i);
+        ASSERT_VK_SUCCESS(err);
+    }
+    VkDescriptorSet descriptor_sets[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = {};
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = VK_DESCRIPTOR_TYPE_RANGE_SIZE;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = ds_layouts;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info,
+                                   descriptor_sets);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create a buffer & bufferView to be used for invalid updates
+    VkBufferCreateInfo buff_ci = {};
+    buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    // This usage is not valid for any descriptor type
+    buff_ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+    buff_ci.size = 256;
+    buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    VkBuffer buffer;
+    err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+
+    VkBufferViewCreateInfo buff_view_ci = {};
+    buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+    buff_view_ci.buffer = buffer;
+    buff_view_ci.format = VK_FORMAT_R8_UNORM;
+    buff_view_ci.range = VK_WHOLE_SIZE;
+    VkBufferView buff_view;
+    err =
+        vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buff_view);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create an image to be used for invalid updates
+    VkImageCreateInfo image_ci = {};
+    image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_ci.imageType = VK_IMAGE_TYPE_2D;
+    image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
+    image_ci.extent.width = 64;
+    image_ci.extent.height = 64;
+    image_ci.extent.depth = 1;
+    image_ci.mipLevels = 1;
+    image_ci.arrayLayers = 1;
+    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_ci.tiling = VK_IMAGE_TILING_LINEAR;
+    image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+    // This usage is not valid for any descriptor type
+    image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+    image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    VkImage image;
+    err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
+    ASSERT_VK_SUCCESS(err);
+    // Bind memory to image
+    VkMemoryRequirements mem_reqs;
+    VkDeviceMemory image_mem;
+    bool pass;
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 0;
+    mem_alloc.memoryTypeIndex = 0;
+    vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
+    mem_alloc.allocationSize = mem_reqs.size;
+    pass =
+        m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
+    ASSERT_TRUE(pass);
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
+    ASSERT_VK_SUCCESS(err);
+    // Now create view for image
+    VkImageViewCreateInfo image_view_ci = {};
+    image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    image_view_ci.image = image;
+    image_view_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
+    image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    image_view_ci.subresourceRange.layerCount = 1;
+    image_view_ci.subresourceRange.baseArrayLayer = 0;
+    image_view_ci.subresourceRange.levelCount = 1;
+    image_view_ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    VkImageView image_view;
+    err = vkCreateImageView(m_device->device(), &image_view_ci, NULL,
+                            &image_view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorBufferInfo buff_info = {};
+    buff_info.buffer = buffer;
+    VkDescriptorImageInfo img_info = {};
+    img_info.imageView = image_view;
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.pTexelBufferView = &buff_view;
+    descriptor_write.pBufferInfo = &buff_info;
+    descriptor_write.pImageInfo = &img_info;
+
+    // These error messages align with VkDescriptorType struct
+    const char *error_msgs[] = {
+        "", // placeholder, no error for SAMPLER descriptor
+        " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
+        " does not have VK_IMAGE_USAGE_SAMPLED_BIT set.",
+        " does not have VK_IMAGE_USAGE_STORAGE_BIT set.",
+        " does not have VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set.",
+        " does not have VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set.",
+        " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
+        " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
+        " does not have VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set.",
+        " does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.",
+        " does not have VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set."};
+    // Start loop at 1 as SAMPLER desc type has no usage bit error
+    for (uint32_t i = 1; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++i) {
+        descriptor_write.descriptorType = VkDescriptorType(i);
+        descriptor_write.dstSet = descriptor_sets[i];
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             error_msgs[i]);
+
+        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0,
+                               NULL);
+
+        m_errorMonitor->VerifyFound();
+        vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[i], NULL);
+    }
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layouts[0], NULL);
+    vkDestroyImage(m_device->device(), image, NULL);
+    vkFreeMemory(m_device->device(), image_mem, NULL);
+    vkDestroyImageView(m_device->device(), image_view, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkDestroyBufferView(m_device->device(), buff_view, NULL);
+    vkFreeDescriptorSets(m_device->device(), ds_pool,
+                         VK_DESCRIPTOR_TYPE_RANGE_SIZE, descriptor_sets);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
+TEST_F(VkLayerTest, DSBufferInfoErrors) {
+    TEST_DESCRIPTION(
+        "Attempt to update buffer descriptor set that has incorrect "
+        "parameters in VkDescriptorBufferInfo struct. This includes:\n"
+        "1. offset value greater than buffer size\n"
+        "2. range value of 0\n"
+        "3. range value greater than buffer (size - offset)");
+    VkResult err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkDescriptorPoolSize ds_type_count = {};
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    ds_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.pNext = NULL;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    err =
+        vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create layout with single uniform buffer descriptor
+    VkDescriptorSetLayoutBinding dsl_binding = {};
+    dsl_binding.binding = 0;
+    dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    dsl_binding.descriptorCount = 1;
+    dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+    dsl_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &dsl_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
+                                      &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSet descriptor_set = {};
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info,
+                                   &descriptor_set);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create a buffer to be used for invalid updates
+    VkBufferCreateInfo buff_ci = {};
+    buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buff_ci.size = 256;
+    buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    VkBuffer buffer;
+    err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+    // Have to bind memory to buffer before descriptor update
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 256;
+    mem_alloc.memoryTypeIndex = 0;
+
+    VkMemoryRequirements mem_reqs;
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
+    bool pass =
+        m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
+    if (!pass) {
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        return;
+    }
+
+    VkDeviceMemory mem;
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorBufferInfo buff_info = {};
+    buff_info.buffer = buffer;
+    // First make offset 1 larger than buffer size
+    buff_info.offset = 257;
+    buff_info.range = VK_WHOLE_SIZE;
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.pTexelBufferView = nullptr;
+    descriptor_write.pBufferInfo = &buff_info;
+    descriptor_write.pImageInfo = nullptr;
+
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    descriptor_write.dstSet = descriptor_set;
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " offset of 257 is greater than buffer ");
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    m_errorMonitor->VerifyFound();
+    // Now cause error due to range of 0
+    buff_info.offset = 0;
+    buff_info.range = 0;
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " range is not VK_WHOLE_SIZE and is zero, which is not allowed.");
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    m_errorMonitor->VerifyFound();
+    // Now cause error due to range exceeding buffer size - offset
+    buff_info.offset = 128;
+    buff_info.range = 200;
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " range is 200 which is greater than buffer size ");
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    m_errorMonitor->VerifyFound();
+    vkFreeMemory(m_device->device(), mem, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
+TEST_F(VkLayerTest, DSAspectBitsErrors) {
+    // TODO : Initially only catching case where DEPTH & STENCIL aspect bits
+    //  are set, but could expand this test to hit more cases.
+    TEST_DESCRIPTION("Attempt to update descriptor sets for images "
+                     "that do not have correct aspect bits sets.");
+    VkResult err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkDescriptorPoolSize ds_type_count = {};
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
+    ds_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.pNext = NULL;
+    ds_pool_ci.maxSets = 5;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    err =
+        vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding dsl_binding = {};
+    dsl_binding.binding = 0;
+    dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
+    dsl_binding.descriptorCount = 1;
+    dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+    dsl_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &dsl_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
+                                      &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSet descriptor_set = {};
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info,
+                                   &descriptor_set);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create an image to be used for invalid updates
+    VkImageCreateInfo image_ci = {};
+    image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_ci.imageType = VK_IMAGE_TYPE_2D;
+    image_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
+    image_ci.extent.width = 64;
+    image_ci.extent.height = 64;
+    image_ci.extent.depth = 1;
+    image_ci.mipLevels = 1;
+    image_ci.arrayLayers = 1;
+    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_ci.tiling = VK_IMAGE_TILING_LINEAR;
+    image_ci.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+    image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+    image_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    VkImage image;
+    err = vkCreateImage(m_device->device(), &image_ci, NULL, &image);
+    ASSERT_VK_SUCCESS(err);
+    // Bind memory to image
+    VkMemoryRequirements mem_reqs;
+    VkDeviceMemory image_mem;
+    bool pass;
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 0;
+    mem_alloc.memoryTypeIndex = 0;
+    vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
+    mem_alloc.allocationSize = mem_reqs.size;
+    pass =
+        m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
+    ASSERT_TRUE(pass);
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), image, image_mem, 0);
+    ASSERT_VK_SUCCESS(err);
+    // Now create view for image
+    VkImageViewCreateInfo image_view_ci = {};
+    image_view_ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    image_view_ci.image = image;
+    image_view_ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
+    image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    image_view_ci.subresourceRange.layerCount = 1;
+    image_view_ci.subresourceRange.baseArrayLayer = 0;
+    image_view_ci.subresourceRange.levelCount = 1;
+    // Setting both depth & stencil aspect bits is illegal for descriptor
+    image_view_ci.subresourceRange.aspectMask =
+        VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+
+    VkImageView image_view;
+    err = vkCreateImageView(m_device->device(), &image_view_ci, NULL,
+                            &image_view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorImageInfo img_info = {};
+    img_info.imageView = image_view;
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.pTexelBufferView = NULL;
+    descriptor_write.pBufferInfo = NULL;
+    descriptor_write.pImageInfo = &img_info;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
+    descriptor_write.dstSet = descriptor_set;
+    const char *error_msg = " please only set either VK_IMAGE_ASPECT_DEPTH_BIT "
+                            "or VK_IMAGE_ASPECT_STENCIL_BIT ";
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         error_msg);
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    m_errorMonitor->VerifyFound();
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyImage(m_device->device(), image, NULL);
+    vkFreeMemory(m_device->device(), image_mem, NULL);
+    vkDestroyImageView(m_device->device(), image_view, NULL);
+    vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
 TEST_F(VkLayerTest, DSTypeMismatch) {
     // Create DS w/ layout of one type and attempt Update w/ mis-matched type
     VkResult err;
@@ -7706,6 +11548,116 @@
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 }
 
+TEST_F(VkLayerTest, RenderPassIncompatible) {
+    TEST_DESCRIPTION("Hit RenderPass incompatible cases. "
+                     "Initial case is drawing with an active renderpass that's "
+                     "not compatible with the bound PSO's creation renderpass");
+    VkResult err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkDescriptorSetLayoutBinding dsl_binding = {};
+    dsl_binding.binding = 0;
+    dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    dsl_binding.descriptorCount = 1;
+    dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+    dsl_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &dsl_binding;
+
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
+                                      &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pNext = NULL;
+    pipeline_layout_ci.setLayoutCount = 1;
+    pipeline_layout_ci.pSetLayouts = &ds_layout;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
+                                 &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkShaderObj vs(m_device, bindStateVertShaderText,
+                   VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, bindStateFragShaderText,
+                   VK_SHADER_STAGE_FRAGMENT_BIT,
+                   this); // We shouldn't need a fragment shader
+                          // but add it to be able to run on more devices
+    // Create a renderpass that will be incompatible with default renderpass
+    VkAttachmentReference attach = {};
+    attach.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    VkAttachmentReference color_att = {};
+    color_att.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+    VkSubpassDescription subpass = {};
+    subpass.inputAttachmentCount = 1;
+    subpass.pInputAttachments = &attach;
+    subpass.colorAttachmentCount = 1;
+    subpass.pColorAttachments = &color_att;
+    VkRenderPassCreateInfo rpci = {};
+    rpci.subpassCount = 1;
+    rpci.pSubpasses = &subpass;
+    rpci.attachmentCount = 1;
+    VkAttachmentDescription attach_desc = {};
+    attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
+    // Format incompatible with PSO RP color attach format B8G8R8A8_UNORM
+    attach_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
+    rpci.pAttachments = &attach_desc;
+    rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    VkRenderPass rp;
+    vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+    VkViewport view_port = {};
+    m_viewports.push_back(view_port);
+    pipe.SetViewport(m_viewports);
+    VkRect2D rect = {};
+    m_scissors.push_back(rect);
+    pipe.SetScissor(m_scissors);
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+
+    VkCommandBufferInheritanceInfo cbii = {};
+    cbii.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+    cbii.renderPass = rp;
+    cbii.subpass = 0;
+    VkCommandBufferBeginInfo cbbi = {};
+    cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    cbbi.pInheritanceInfo = &cbii;
+    vkBeginCommandBuffer(m_commandBuffer->handle(), &cbbi);
+    VkRenderPassBeginInfo rpbi = {};
+    rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+    rpbi.framebuffer = m_framebuffer;
+    rpbi.renderPass = rp;
+    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &rpbi,
+                         VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
+                      VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " is incompatible w/ gfx pipeline ");
+    // Render triangle (the error should trigger on the attempt to draw).
+    Draw(3, 1, 0, 0);
+
+    // Finalize recording of the command buffer
+    EndCommandBuffer();
+
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
+}
+
 TEST_F(VkLayerTest, NumBlendAttachMismatch) {
     // Create Pipeline where the number of blend attachments doesn't match the
     // number of color attachments.  In this case, we don't add any color
@@ -7810,6 +11762,17 @@
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 }
 
+TEST_F(VkLayerTest, MissingClearAttachment) {
+    TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment "
+                     "structure passed to vkCmdClearAttachments");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "vkCmdClearAttachments() attachment index 1 not found in attachment "
+                                         "reference array of active subpass 0");
+
+    VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailCmdClearAttachments);
+    m_errorMonitor->VerifyFound();
+}
+
 TEST_F(VkLayerTest, ClearCmdNoDraw) {
     // Create CommandBuffer where we add ClearCmd for FB Color attachment prior
     // to issuing a Draw
@@ -8030,6 +11993,180 @@
     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 }
+
+TEST_F(VkLayerTest, VertexBufferInvalid) {
+    TEST_DESCRIPTION("Submit a command buffer using deleted vertex buffer, "
+                     "delete a buffer twice, use an invalid offset for each "
+                     "buffer type, and attempt to bind a null buffer");
+
+    const char *deleted_buffer_in_command_buffer = "Cannot submit cmd buffer "
+                                                   "using deleted buffer ";
+    const char *double_destroy_message = "Cannot free buffer 0x";
+    const char *invalid_offset_message = "vkBindBufferMemory(): "
+                                         "memoryOffset is 0x";
+    const char *invalid_storage_buffer_offset_message = "vkBindBufferMemory(): "
+                                                        "storage memoryOffset "
+                                                        "is 0x";
+    const char *invalid_texel_buffer_offset_message = "vkBindBufferMemory(): "
+                                                      "texel memoryOffset "
+                                                      "is 0x";
+    const char *invalid_uniform_buffer_offset_message = "vkBindBufferMemory(): "
+                                                        "uniform memoryOffset "
+                                                        "is 0x";
+    const char *bind_null_buffer_message = "In vkBindBufferMemory, attempting"
+                                           " to Bind Obj(0x";
+    const char *free_invalid_buffer_message = "Request to delete memory "
+                                              "object 0x";
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitViewport());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
+    pipe_ms_state_ci.sType =
+        VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+    pipe_ms_state_ci.pNext = NULL;
+    pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+    pipe_ms_state_ci.sampleShadingEnable = 0;
+    pipe_ms_state_ci.minSampleShading = 1.0;
+    pipe_ms_state_ci.pSampleMask = nullptr;
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    VkPipelineLayout pipeline_layout;
+
+    VkResult err = vkCreatePipelineLayout(m_device->device(),
+                                          &pipeline_layout_ci, nullptr,
+                                          &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkShaderObj vs(m_device, bindStateVertShaderText,
+                   VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, bindStateFragShaderText,
+                   VK_SHADER_STAGE_FRAGMENT_BIT,
+                   this);
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+    pipe.SetMSAA(&pipe_ms_state_ci);
+    pipe.SetViewport(m_viewports);
+    pipe.SetScissor(m_scissors);
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+
+    BeginCommandBuffer();
+    vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(),
+                      VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+
+    {
+        // Create and bind a vertex buffer in a reduced scope, which will cause
+        // it to be deleted upon leaving this scope
+        const float vbo_data[3] = {1.f, 0.f, 1.f};
+        VkVerticesObj draw_verticies(m_device, 1, 1, sizeof(vbo_data),
+                                     3, vbo_data);
+        draw_verticies.BindVertexBuffers(m_commandBuffer->handle());
+        draw_verticies.AddVertexInputToPipe(pipe);
+    }
+
+    Draw(1, 0, 0, 0);
+
+    EndCommandBuffer();
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         deleted_buffer_in_command_buffer);
+    QueueCommandBuffer(false);
+    m_errorMonitor->VerifyFound();
+
+    {
+        // Create and bind a vertex buffer in a reduced scope, and delete it
+        // twice, the second through the destructor
+        VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+                                 VkBufferTest::eDoubleDelete);
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             double_destroy_message);
+        buffer_test.TestDoubleDestroy();
+    }
+    m_errorMonitor->VerifyFound();
+
+    if (VkBufferTest::
+            GetTestConditionValid(m_device,
+                                  VkBufferTest::eInvalidMemoryOffset)) {
+        // Create and bind a memory buffer with an invalid offset.
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             invalid_offset_message);
+        VkBufferTest buffer_test(m_device,
+                                  VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
+                                  VkBufferTest::eInvalidMemoryOffset);
+        (void) buffer_test;
+        m_errorMonitor->VerifyFound();
+    }
+
+    if (VkBufferTest::
+            GetTestConditionValid(m_device,
+                                  VkBufferTest::eInvalidDeviceOffset,
+                                  VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
+        // Create and bind a memory buffer with an invalid offset again,
+        // but look for a texel buffer message.
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             invalid_texel_buffer_offset_message);
+        VkBufferTest buffer_test(m_device,
+                                  VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
+                                  VkBufferTest::eInvalidDeviceOffset);
+        (void) buffer_test;
+        m_errorMonitor->VerifyFound();
+    }
+
+    if (VkBufferTest::
+            GetTestConditionValid(m_device,
+                                  VkBufferTest::eInvalidDeviceOffset,
+                                  VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
+        // Create and bind a memory buffer with an invalid offset again, but
+        // look for a uniform buffer message.
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             invalid_uniform_buffer_offset_message);
+        VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
+                                  VkBufferTest::eInvalidDeviceOffset);
+        (void) buffer_test;
+        m_errorMonitor->VerifyFound();
+    }
+
+    if (VkBufferTest::
+            GetTestConditionValid(m_device,
+                                  VkBufferTest::eInvalidDeviceOffset,
+                                  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
+        // Create and bind a memory buffer with an invalid offset again, but
+        // look for a storage buffer message.
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             invalid_storage_buffer_offset_message);
+        VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+                                  VkBufferTest::eInvalidDeviceOffset);
+        (void) buffer_test;
+        m_errorMonitor->VerifyFound();
+    }
+
+    {
+        // Attempt to bind a null buffer.
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             bind_null_buffer_message);
+        VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+                                  VkBufferTest::eBindNullBuffer);
+        (void) buffer_test;
+        m_errorMonitor->VerifyFound();
+    }
+
+    {
+        // Attempt to use an invalid handle to delete a buffer.
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             free_invalid_buffer_message);
+        VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
+                                 VkBufferTest::eFreeInvalidHandle);
+        (void) buffer_test;
+    }
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+}
+
 // INVALID_IMAGE_LAYOUT tests (one other case is hit by MapMemWithoutHostVisibleBit and not here)
 TEST_F(VkLayerTest, InvalidImageLayout) {
     TEST_DESCRIPTION("Hit all possible validation checks associated with the "
@@ -8188,14 +12325,14 @@
     // perf warning for GENERAL layout on DS attachment
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-        "Layout for depth attachment is GENERAL but should be DEPTH_STENCIL_ATTACHMENT_OPTIMAL.");
+        "GENERAL layout for depth attachment may not give optimal performance.");
     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
     m_errorMonitor->VerifyFound();
     // error w/ non-ds opt or GENERAL layout for color attachment
     attach.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
-        "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL or GENERAL.");
+        "Layout for depth attachment is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.");
     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
     m_errorMonitor->VerifyFound();
     // For this error we need a valid renderpass so create default one
@@ -8220,6 +12357,269 @@
     vkDestroyImage(m_device->device(), src_image, NULL);
     vkDestroyImage(m_device->device(), dst_image, NULL);
 }
+
+TEST_F(VkLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
+    TEST_DESCRIPTION("Positive test where we create a renderpass with an "
+                     "attachment that uses LOAD_OP_CLEAR, the first subpass "
+                     "has a valid layout, and a second subpass then uses a "
+                     "valid *READ_ONLY* layout.");
+    m_errorMonitor->ExpectSuccess();
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkAttachmentReference attach[2] = {};
+    attach[0].attachment = 0;
+    attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    attach[1].attachment = 0;
+    attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
+    VkSubpassDescription subpasses[2] = {};
+    // First subpass clears DS attach on load
+    subpasses[0].pDepthStencilAttachment = &attach[0];
+    // 2nd subpass reads in DS as input attachment
+    subpasses[1].inputAttachmentCount = 1;
+    subpasses[1].pInputAttachments = &attach[1];
+    VkAttachmentDescription attach_desc = {};
+    attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
+    attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
+    attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+    attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    attach_desc.initialLayout =
+        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
+    VkRenderPassCreateInfo rpci = {};
+    rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    rpci.attachmentCount = 1;
+    rpci.pAttachments = &attach_desc;
+    rpci.subpassCount = 2;
+    rpci.pSubpasses = subpasses;
+
+    // Now create RenderPass and verify no errors
+    VkRenderPass rp;
+    vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+    m_errorMonitor->VerifyNotFound();
+
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
+}
+
+TEST_F(VkLayerTest, FramebufferIncompatible) {
+    TEST_DESCRIPTION("Bind a secondary command buffer with with a framebuffer "
+                     "that does not match the framebuffer for the active "
+                     "renderpass.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    // A renderpass with one color attachment.
+    VkAttachmentDescription attachment = {
+        0,
+        VK_FORMAT_B8G8R8A8_UNORM,
+        VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_UNDEFINED,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+
+    VkAttachmentReference att_ref = {0,
+                                     VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
+
+    VkSubpassDescription subpass = {0,       VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                    0,       nullptr,
+                                    1,       &att_ref,
+                                    nullptr, nullptr,
+                                    0,       nullptr};
+
+    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+                                   nullptr,
+                                   0,
+                                   1,
+                                   &attachment,
+                                   1,
+                                   &subpass,
+                                   0,
+                                   nullptr};
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkImageObj image(m_device);
+    image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM,
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+        nullptr,
+        0,
+        image.handle(),
+        VK_IMAGE_VIEW_TYPE_2D,
+        VK_FORMAT_B8G8R8A8_UNORM,
+        {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
+         VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
+        {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+                                   nullptr,
+                                   0,
+                                   rp,
+                                   1,
+                                   &view,
+                                   32,
+                                   32,
+                                   1};
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    VkCommandBufferAllocateInfo cbai = {};
+    cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    cbai.commandPool = m_commandPool;
+    cbai.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
+    cbai.commandBufferCount = 1;
+
+    VkCommandBuffer sec_cb;
+    err = vkAllocateCommandBuffers(m_device->device(), &cbai, &sec_cb);
+    ASSERT_VK_SUCCESS(err);
+    VkCommandBufferBeginInfo cbbi = {};
+    VkCommandBufferInheritanceInfo cbii = {};
+    cbii.renderPass = renderPass();
+    cbii.framebuffer = fb;
+    cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    cbbi.pNext = NULL;
+    cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
+                 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
+    cbbi.pInheritanceInfo = &cbii;
+    vkBeginCommandBuffer(sec_cb, &cbbi);
+    vkEndCommandBuffer(sec_cb);
+
+    BeginCommandBuffer();
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        " that is not the same as the primaryCB's current active framebuffer ");
+    vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &sec_cb);
+    m_errorMonitor->VerifyFound();
+    // Cleanup
+    vkDestroyImageView(m_device->device(), view, NULL);
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
+    vkDestroyFramebuffer(m_device->device(), fb, NULL);
+}
+
+TEST_F(VkLayerTest, ColorBlendLogicOpTests) {
+    TEST_DESCRIPTION("If logicOp is available on the device, set it to an "
+                     "invalid value. If logicOp is not available, attempt to "
+                     "use it and verify that we see the correct error.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    auto features = m_device->phy().features();
+    // Set the expected error depending on whether or not logicOp available
+    if (VK_FALSE == features.logicOp) {
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                             "If logic operations feature not "
+                                             "enabled, logicOpEnable must be "
+                                             "VK_FALSE");
+    } else {
+        m_errorMonitor->SetDesiredFailureMsg(
+            VK_DEBUG_REPORT_ERROR_BIT_EXT,
+            ", logicOp must be a valid VkLogicOp value");
+    }
+    // Create a pipeline using logicOp
+    VkResult err;
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL,
+                                 &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineViewportStateCreateInfo vp_state_ci = {};
+    vp_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+    vp_state_ci.viewportCount = 1;
+    VkViewport vp = {};           // Just need dummy vp to point to
+    vp_state_ci.pViewports = &vp;
+    vp_state_ci.scissorCount = 1;
+    VkRect2D scissors = {}; // Dummy scissors to point to
+    vp_state_ci.pScissors = &scissors;
+    // No dynamic state
+    VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
+    dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+
+    VkPipelineShaderStageCreateInfo shaderStages[2];
+    memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
+
+    VkShaderObj vs(m_device, bindStateVertShaderText,
+                   VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, bindStateFragShaderText,
+                   VK_SHADER_STAGE_FRAGMENT_BIT,
+                   this);
+    shaderStages[0] = vs.GetStageCreateInfo();
+    shaderStages[1] = fs.GetStageCreateInfo();
+
+    VkPipelineVertexInputStateCreateInfo vi_ci = {};
+    vi_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+
+    VkPipelineInputAssemblyStateCreateInfo ia_ci = {};
+    ia_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+    ia_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+    VkPipelineRasterizationStateCreateInfo rs_ci = {};
+    rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+
+    VkPipelineColorBlendAttachmentState att = {};
+    att.blendEnable = VK_FALSE;
+    att.colorWriteMask = 0xf;
+
+    VkPipelineColorBlendStateCreateInfo cb_ci = {};
+    cb_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+    // Enable logicOp & set logicOp to value 1 beyond allowed entries
+    cb_ci.logicOpEnable = VK_TRUE;
+    cb_ci.logicOp = VK_LOGIC_OP_RANGE_SIZE; // This should cause an error
+    cb_ci.attachmentCount = 1;
+    cb_ci.pAttachments = &att;
+
+    VkGraphicsPipelineCreateInfo gp_ci = {};
+    gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+    gp_ci.stageCount = 2;
+    gp_ci.pStages = shaderStages;
+    gp_ci.pVertexInputState = &vi_ci;
+    gp_ci.pInputAssemblyState = &ia_ci;
+    gp_ci.pViewportState = &vp_state_ci;
+    gp_ci.pRasterizationState = &rs_ci;
+    gp_ci.pColorBlendState = &cb_ci;
+    gp_ci.pDynamicState = &dyn_state_ci;
+    gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
+    gp_ci.layout = pipeline_layout;
+    gp_ci.renderPass = renderPass();
+
+    VkPipelineCacheCreateInfo pc_ci = {};
+    pc_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+
+    VkPipeline pipeline;
+    VkPipelineCache pipelineCache;
+    err =
+        vkCreatePipelineCache(m_device->device(), &pc_ci, NULL, &pipelineCache);
+    ASSERT_VK_SUCCESS(err);
+
+    err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1,
+                                    &gp_ci, NULL, &pipeline);
+    m_errorMonitor->VerifyFound();
+    if (VK_SUCCESS == err) {
+        vkDestroyPipeline(m_device->device(), pipeline, NULL);
+    }
+    m_errorMonitor->VerifyFound();
+    vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+}
 #endif // DRAW_STATE_TESTS
 
 #if THREADING_TESTS
@@ -8233,7 +12633,7 @@
 extern "C" void *AddToCommandBuffer(void *arg) {
     struct thread_data_struct *data = (struct thread_data_struct *)arg;
 
-    for (int i = 0; i < 10000; i++) {
+    for (int i = 0; i < 80000; i++) {
         vkCmdSetEvent(data->commandBuffer, data->event,
                       VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
         if (data->bailout) {
@@ -8277,6 +12677,18 @@
     data.event = event;
     data.bailout = false;
     m_errorMonitor->SetBailout(&data.bailout);
+
+    // First do some correct operations using multiple threads.
+    // Add many entries to command buffer from another thread.
+    test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
+    // Make non-conflicting calls from this thread at the same time.
+    for (int i = 0; i < 80000; i++) {
+        uint32_t count;
+        vkEnumeratePhysicalDevices(instance(), &count, NULL);
+    }
+    test_platform_thread_join(thread, NULL);
+
+    // Then do some incorrect operations using multiple threads.
     // Add many entries to command buffer from another thread.
     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
     // Add many entries to command buffer from this thread at the same time.
@@ -8296,6 +12708,9 @@
 
 #if SHADER_CHECKER_TESTS
 TEST_F(VkLayerTest, InvalidSPIRVCodeSize) {
+    TEST_DESCRIPTION("Test that an error is produced for a spirv module "
+                     "with an impossible code size");
+
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "Invalid SPIR-V header");
 
@@ -8321,6 +12736,9 @@
 }
 
 TEST_F(VkLayerTest, InvalidSPIRVMagic) {
+    TEST_DESCRIPTION("Test that an error is produced for a spirv module "
+                     "with a bad magic number");
+
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "Invalid SPIR-V magic number");
 
@@ -8375,6 +12793,8 @@
 #endif
 
 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed) {
+    TEST_DESCRIPTION("Test that a warning is produced for a vertex output that "
+                     "is not consumed by the fragment stage");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                          "not consumed by fragment shader");
 
@@ -8418,6 +12838,9 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
+    TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
+                     "which is not present in the outputs of the previous stage");
+
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "not written by vertex shader");
 
@@ -8460,6 +12883,9 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvidedInBlock) {
+    TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
+                     "within an interace block, which is not present in the outputs "
+                     "of the previous stage.");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "not written by vertex shader");
 
@@ -8502,6 +12928,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
+    TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes "
+                     "across the VS->FS interface");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "Type mismatch on location 0.0: 'ptr to "
                                          "output arr[2] of float32' vs 'ptr to "
@@ -8548,6 +12976,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
+    TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
+                     "the VS->FS interface");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "Type mismatch on location 0");
 
@@ -8592,6 +13022,9 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
+    TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
+                     "the VS->FS interface, when the variable is contained within "
+                     "an interface block");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "Type mismatch on location 0");
 
@@ -8636,6 +13069,9 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
+    TEST_DESCRIPTION("Test that an error is produced for location mismatches across "
+                     "the VS->FS interface; This should manifest as a not-written/not-consumed "
+                     "pair, but flushes out broken walking of the interfaces");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "location 0.0 which is not written by vertex shader");
 
@@ -8680,6 +13116,9 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
+    TEST_DESCRIPTION("Test that an error is produced for component mismatches across the "
+                     "VS->FS interface. It's not enough to have the same set of locations in "
+                     "use; matching is defined in terms of spirv variables.");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "location 0.1 which is not written by vertex shader");
 
@@ -8724,6 +13163,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
+    TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is "
+                     "not consumed by the vertex shader");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                          "location 0 not consumed by VS");
 
@@ -8775,6 +13216,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
+    TEST_DESCRIPTION("Test that a warning is produced for a location mismatch on "
+                     "vertex attributes. This flushes out bad behavior in the interface walker");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                          "location 0 not consumed by VS");
 
@@ -8827,6 +13270,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
+    TEST_DESCRIPTION("Test that an error is produced for a VS input which is not "
+                     "provided by a vertex attribute");
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "VS consumes input at location 0 but not provided");
@@ -8870,6 +13315,9 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
+    TEST_DESCRIPTION("Test that an error is produced for a mismatch between the "
+                     "fundamental type (float/int/uint) of an attribute and the "
+                     "VS input that consumes it");
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "location 0 does not match VS input type");
@@ -8923,6 +13371,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineDuplicateStage) {
+    TEST_DESCRIPTION("Test that an error is produced for a pipeline containing multiple "
+                     "shaders for the same stage");
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "Multiple shaders provided for stage VK_SHADER_STAGE_VERTEX_BIT");
@@ -8966,6 +13416,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineAttribMatrixType) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed "
+                     "as vertex attributes");
     m_errorMonitor->ExpectSuccess();
 
     ASSERT_NO_FATAL_FAILURE(InitState());
@@ -9077,6 +13529,68 @@
     m_errorMonitor->VerifyNotFound();
 }
 
+TEST_F(VkLayerTest, CreatePipelineAttribComponents)
+{
+    TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute "
+                     "through multiple VS inputs, each consuming a different subset of the "
+                     "components.");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkVertexInputBindingDescription input_binding;
+    memset(&input_binding, 0, sizeof(input_binding));
+
+    VkVertexInputAttributeDescription input_attribs[3];
+    memset(input_attribs, 0, sizeof(input_attribs));
+
+    for (int i = 0; i < 3; i++) {
+        input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
+        input_attribs[i].location = i;
+    }
+
+    char const *vsSource =
+        "#version 450\n"
+        "\n"
+        "layout(location=0) in vec4 x;\n"
+        "layout(location=1) in vec3 y1;\n"
+        "layout(location=1, component=3) in float y2;\n"
+        "layout(location=2) in vec4 z;\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "void main(){\n"
+        "   gl_Position = x + vec4(y1, y2) + z;\n"
+        "}\n";
+    char const *fsSource =
+        "#version 450\n"
+        "\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    pipe.AddVertexInputBindings(&input_binding, 1);
+    pipe.AddVertexInputAttribs(input_attribs, 3);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    m_errorMonitor->VerifyNotFound();
+}
+
 TEST_F(VkLayerTest, CreatePipelineSimplePositive)
 {
     m_errorMonitor->ExpectSuccess();
@@ -9119,6 +13633,9 @@
 
 TEST_F(VkLayerTest, CreatePipelineRelaxedTypeMatch)
 {
+    TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules "
+                     "set out in 14.1.3: fundamental type must match, and producer side must "
+                     "have at least as many components");
     m_errorMonitor->ExpectSuccess();
 
     // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
@@ -9161,13 +13678,19 @@
     descriptorSet.AppendDummy();
     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
 
-    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+    VkResult err = VK_SUCCESS;
+    err =
+        pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+    ASSERT_VK_SUCCESS(err);
+
 
     m_errorMonitor->VerifyNotFound();
 }
 
 TEST_F(VkLayerTest, CreatePipelineTessPerVertex)
 {
+    TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables "
+                     "passed between the TCS and TES stages");
     m_errorMonitor->ExpectSuccess();
 
     ASSERT_NO_FATAL_FAILURE(InitState());
@@ -9244,6 +13767,10 @@
 
 TEST_F(VkLayerTest, CreatePipelineGeometryInputBlockPositive)
 {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined "
+                     "interface block passed into the geometry shader. This "
+                     "is interesting because the 'extra' array level is not "
+                     "present on the member type, but on the block instance.");
     m_errorMonitor->ExpectSuccess();
 
     ASSERT_NO_FATAL_FAILURE(InitState());
@@ -9298,6 +13825,9 @@
 
 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch)
 {
+    TEST_DESCRIPTION("Test that an error is produced for a variable output from "
+                     "the TCS without the patch decoration, but consumed in the TES "
+                     "with the decoration.");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "is per-vertex in tessellation control shader stage "
                                          "but per-patch in tessellation evaluation shader stage");
@@ -9375,6 +13905,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
+    TEST_DESCRIPTION("Test that an error is produced for a vertex attribute setup where multiple "
+                     "bindings provide the same location");
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
         "Duplicate vertex input binding descriptions for binding 0");
@@ -9429,12 +13961,15 @@
 }
 
 TEST_F(VkLayerTest, CreatePipeline64BitAttributesPositive) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex "
+                     "attributes. This is interesting because they consume multiple "
+                     "locations.");
     m_errorMonitor->ExpectSuccess();
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
 
-    if (!m_device->phy().features().tessellationShader) {
+    if (!m_device->phy().features().shaderFloat64) {
         printf("Device does not support 64bit vertex attributes; skipped.\n");
         return;
     }
@@ -9496,6 +14031,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
+    TEST_DESCRIPTION("Test that an error is produced for a FS which does not "
+                     "provide an output for one of the pipeline's color attachments");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "Attachment 0 not written by FS");
 
@@ -9537,6 +14074,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
+    TEST_DESCRIPTION("Test that a warning is produced for a FS which provides a spurious "
+                     "output with no matching attachment");
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_WARNING_BIT_EXT,
         "FS writes to output location 1 with no matching attachment");
@@ -9584,6 +14123,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
+    TEST_DESCRIPTION("Test that an error is produced for a mismatch between the fundamental "
+                     "type of an FS output variable, and the format of the corresponding attachment");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "does not match FS output type");
 
@@ -9627,6 +14168,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineUniformBlockNotProvided) {
+    TEST_DESCRIPTION("Test that an error is produced for a shader consuming a uniform "
+                     "block which has no corresponding binding in the pipeline layout");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "not declared in pipeline layout");
 
@@ -9670,6 +14213,8 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelinePushConstantsNotInLayout) {
+    TEST_DESCRIPTION("Test that an error is produced for a shader consuming push constants "
+                     "which are not provided in the pipeline layout");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "not declared in layout");
 
@@ -9713,6 +14258,501 @@
     m_errorMonitor->VerifyFound();
 }
 
+TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptor) {
+    TEST_DESCRIPTION("Test that an error is produced for a compute pipeline consuming a "
+                     "descriptor which is not provided in the pipeline layout");
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "Shader uses descriptor slot 0.0");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    char const *csSource =
+        "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) buffer block { vec4 x; };\n"
+        "void main(){\n"
+        "   x = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    VkComputePipelineCreateInfo cpci = {
+        VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+        nullptr, 0, {
+          VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+          nullptr, 0, VK_SHADER_STAGE_COMPUTE_BIT,
+          cs.handle(), "main", nullptr
+        },
+        descriptorSet.GetPipelineLayout(),
+        VK_NULL_HANDLE, -1
+    };
+
+    VkPipeline pipe;
+    VkResult err = vkCreateComputePipelines(
+        m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+}
+
+TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a "
+                     "descriptor-backed resource which is not provided, but the shader does not "
+                     "statically use it. This is interesting because it requires compute pipelines "
+                     "to have a proper descriptor use walk, which they didn't for some time.");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    char const *csSource =
+        "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) buffer block { vec4 x; };\n"
+        "void main(){\n"
+        "   // x is not used.\n"
+        "}\n";
+
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    VkComputePipelineCreateInfo cpci = {
+        VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+        nullptr, 0, {
+          VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+          nullptr, 0, VK_SHADER_STAGE_COMPUTE_BIT,
+          cs.handle(), "main", nullptr
+        },
+        descriptorSet.GetPipelineLayout(),
+        VK_NULL_HANDLE, -1
+    };
+
+    VkPipeline pipe;
+    VkResult err = vkCreateComputePipelines(
+        m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyNotFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+}
+
+TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
+    TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a "
+                     "descriptor-backed resource of a mismatched type");
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "but descriptor of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkDescriptorSetLayoutBinding binding = {
+        0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+        1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+    };
+    VkDescriptorSetLayoutCreateInfo dslci = {
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr,
+        0, 1, &binding
+    };
+    VkDescriptorSetLayout dsl;
+    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci,
+                                               nullptr, &dsl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo plci = {
+        VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
+        0, 1, &dsl, 0, nullptr
+    };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci,
+                                 nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+
+    char const *csSource =
+        "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) buffer block { vec4 x; };\n"
+        "void main() {\n"
+        "   x.x = 1.0f;\n"
+        "}\n";
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkComputePipelineCreateInfo cpci = {
+        VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, nullptr,
+        0, {
+            VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+            nullptr, 0, VK_SHADER_STAGE_COMPUTE_BIT,
+            cs.handle(), "main", nullptr
+        },
+        pl, VK_NULL_HANDLE, -1
+    };
+
+    VkPipeline pipe;
+    err = vkCreateComputePipelines(
+            m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
+}
+
+TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
+                     "sampler portion of a combined image + sampler");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkDescriptorSetLayoutBinding bindings[] = {
+        {
+            0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+            1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+        },
+        {
+            1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+            1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+        },
+        {
+            2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+            1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+        },
+    };
+    VkDescriptorSetLayoutCreateInfo dslci = {
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr,
+        0, 3, bindings
+    };
+    VkDescriptorSetLayout dsl;
+    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci,
+                                               nullptr, &dsl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo plci = {
+        VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
+        0, 1, &dsl, 0, nullptr
+    };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci,
+                                 nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+
+    char const *csSource =
+        "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) uniform sampler s;\n"
+        "layout(set=0, binding=1) uniform texture2D t;\n"
+        "layout(set=0, binding=2) buffer block { vec4 x; };\n"
+        "void main() {\n"
+        "   x = texture(sampler2D(t, s), vec2(0));\n"
+        "}\n";
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkComputePipelineCreateInfo cpci = {
+        VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, nullptr,
+        0, {
+            VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+            nullptr, 0, VK_SHADER_STAGE_COMPUTE_BIT,
+            cs.handle(), "main", nullptr
+        },
+        pl, VK_NULL_HANDLE, -1
+    };
+
+    VkPipeline pipe;
+    err = vkCreateComputePipelines(
+            m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyNotFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
+}
+
+TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
+                     "image portion of a combined image + sampler");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkDescriptorSetLayoutBinding bindings[] = {
+        {
+            0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+            1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+        },
+        {
+            1, VK_DESCRIPTOR_TYPE_SAMPLER,
+            1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+        },
+        {
+            2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+            1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+        },
+    };
+    VkDescriptorSetLayoutCreateInfo dslci = {
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr,
+        0, 3, bindings
+    };
+    VkDescriptorSetLayout dsl;
+    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci,
+                                               nullptr, &dsl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo plci = {
+        VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
+        0, 1, &dsl, 0, nullptr
+    };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci,
+                                 nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+
+    char const *csSource =
+        "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) uniform texture2D t;\n"
+        "layout(set=0, binding=1) uniform sampler s;\n"
+        "layout(set=0, binding=2) buffer block { vec4 x; };\n"
+        "void main() {\n"
+        "   x = texture(sampler2D(t, s), vec2(0));\n"
+        "}\n";
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkComputePipelineCreateInfo cpci = {
+        VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, nullptr,
+        0, {
+            VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+            nullptr, 0, VK_SHADER_STAGE_COMPUTE_BIT,
+            cs.handle(), "main", nullptr
+        },
+        pl, VK_NULL_HANDLE, -1
+    };
+
+    VkPipeline pipe;
+    err = vkCreateComputePipelines(
+            m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyNotFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
+}
+
+TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming "
+                     "both the sampler and the image of a combined image+sampler "
+                     "but via separate variables");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkDescriptorSetLayoutBinding bindings[] = {
+        {
+            0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+            1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+        },
+        {
+            1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+            1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr
+        },
+    };
+    VkDescriptorSetLayoutCreateInfo dslci = {
+        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr,
+        0, 2, bindings
+    };
+    VkDescriptorSetLayout dsl;
+    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci,
+                                               nullptr, &dsl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo plci = {
+        VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
+        0, 1, &dsl, 0, nullptr
+    };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci,
+                                 nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+
+    char const *csSource =
+        "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) uniform texture2D t;\n"
+        "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
+        "layout(set=0, binding=1) buffer block { vec4 x; };\n"
+        "void main() {\n"
+        "   x = texture(sampler2D(t, s), vec2(0));\n"
+        "}\n";
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkComputePipelineCreateInfo cpci = {
+        VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, nullptr,
+        0, {
+            VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+            nullptr, 0, VK_SHADER_STAGE_COMPUTE_BIT,
+            cs.handle(), "main", nullptr
+        },
+        pl, VK_NULL_HANDLE, -1
+    };
+
+    VkPipeline pipe;
+    err = vkCreateComputePipelines(
+            m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyNotFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
+}
+
+TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
+    TEST_DESCRIPTION("Test that an error is produced when an image view type "
+                     "does not match the dimensionality declared in the shader");
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    char const *vsSource =
+        "#version 450\n"
+        "\n"
+        "out gl_PerVertex { vec4 gl_Position; };\n"
+        "void main() { gl_Position = vec4(0); }\n";
+    char const *fsSource =
+        "#version 450\n"
+        "\n"
+        "layout(set=0, binding=0) uniform sampler3D s;\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main() {\n"
+        "   color = texture(s, vec3(0));\n"
+        "}\n";
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+
+    VkTextureObj texture(m_device, nullptr);
+    VkSamplerObj sampler(m_device);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendSamplerTexture(&sampler, &texture);
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+    ASSERT_VK_SUCCESS(err);
+
+    BeginCommandBuffer();
+
+    m_commandBuffer->BindPipeline(pipe);
+    m_commandBuffer->BindDescriptorSet(descriptorSet);
+
+    VkViewport viewport = { 0, 0, 16, 16, 0, 1 };
+    vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
+    VkRect2D scissor = { { 0, 0 }, { 16, 16 } };
+    vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
+
+    // error produced here.
+    vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
+
+    m_errorMonitor->VerifyFound();
+
+    EndCommandBuffer();
+}
+
+TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
+    TEST_DESCRIPTION("Test that an error is produced when a multisampled images "
+                     "are consumed via singlesample images types in the shader, or vice versa.");
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "requires bound image to have multiple samples");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    char const *vsSource =
+        "#version 450\n"
+        "\n"
+        "out gl_PerVertex { vec4 gl_Position; };\n"
+        "void main() { gl_Position = vec4(0); }\n";
+    char const *fsSource =
+        "#version 450\n"
+        "\n"
+        "layout(set=0, binding=0) uniform sampler2DMS s;\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main() {\n"
+        "   color = texelFetch(s, ivec2(0), 0);\n"
+        "}\n";
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+
+    VkTextureObj texture(m_device, nullptr);
+    VkSamplerObj sampler(m_device);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendSamplerTexture(&sampler, &texture);
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+    ASSERT_VK_SUCCESS(err);
+
+    BeginCommandBuffer();
+
+    m_commandBuffer->BindPipeline(pipe);
+    m_commandBuffer->BindDescriptorSet(descriptorSet);
+
+    VkViewport viewport = { 0, 0, 16, 16, 0, 1 };
+    vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
+    VkRect2D scissor = { { 0, 0 }, { 16, 16 } };
+    vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
+
+    // error produced here.
+    vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
+
+    m_errorMonitor->VerifyFound();
+
+    EndCommandBuffer();
+}
+
 #endif // SHADER_CHECKER_TESTS
 
 #if DEVICE_LIMITS_TESTS
@@ -9787,62 +14827,44 @@
 
     m_errorMonitor->VerifyFound();
 }
-
-TEST_F(VkLayerTest, UpdateBufferAlignment) {
-    uint32_t updateData[] = {1, 2, 3, 4, 5, 6, 7, 8};
-
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "dstOffset, is not a multiple of 4");
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
-    vk_testing::Buffer buffer;
-    buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
-
-    BeginCommandBuffer();
-    // Introduce failure by using offset that is not multiple of 4
-    m_commandBuffer->UpdateBuffer(buffer.handle(), 1, 4, updateData);
-    m_errorMonitor->VerifyFound();
-
-    // Introduce failure by using size that is not multiple of 4
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "dataSize, is not a multiple of 4");
-
-    m_commandBuffer->UpdateBuffer(buffer.handle(), 0, 6, updateData);
-    m_errorMonitor->VerifyFound();
-    EndCommandBuffer();
-}
-
-TEST_F(VkLayerTest, FillBufferAlignment) {
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "dstOffset, is not a multiple of 4");
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
-    vk_testing::Buffer buffer;
-    buffer.init_as_dst(*m_device, (VkDeviceSize)20, reqs);
-
-    BeginCommandBuffer();
-    // Introduce failure by using offset that is not multiple of 4
-    m_commandBuffer->FillBuffer(buffer.handle(), 1, 4, 0x11111111);
-    m_errorMonitor->VerifyFound();
-
-    // Introduce failure by using size that is not multiple of 4
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "size, is not a multiple of 4");
-
-    m_commandBuffer->FillBuffer(buffer.handle(), 0, 6, 0x11111111);
-
-    m_errorMonitor->VerifyFound();
-
-    EndCommandBuffer();
-}
-
 #endif // DEVICE_LIMITS_TESTS
 
 #if IMAGE_TESTS
+TEST_F(VkLayerTest, AttachmentDescriptionUndefinedFormat) {
+    TEST_DESCRIPTION("Create a render pass with an attachment description "
+                     "format set to VK_FORMAT_UNDEFINED");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "format is VK_FORMAT_UNDEFINED");
+
+    VkAttachmentReference color_attach = {};
+    color_attach.layout = VK_IMAGE_LAYOUT_GENERAL;
+    color_attach.attachment = 0;
+    VkSubpassDescription subpass = {};
+    subpass.colorAttachmentCount = 1;
+    subpass.pColorAttachments = &color_attach;
+
+    VkRenderPassCreateInfo rpci = {};
+    rpci.subpassCount = 1;
+    rpci.pSubpasses = &subpass;
+    rpci.attachmentCount = 1;
+    VkAttachmentDescription attach_desc = {};
+    attach_desc.format = VK_FORMAT_UNDEFINED;
+    rpci.pAttachments = &attach_desc;
+    rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    VkRenderPass rp;
+    VkResult result = vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+
+    m_errorMonitor->VerifyFound();
+
+    if (result == VK_SUCCESS) {
+        vkDestroyRenderPass(m_device->device(), rp, NULL);
+    }
+}
+
 TEST_F(VkLayerTest, InvalidImageView) {
     VkResult err;
 
@@ -9893,19 +14915,19 @@
                             &view);
 
     m_errorMonitor->VerifyFound();
+    vkDestroyImage(m_device->device(), image, NULL);
 }
 
-TEST_F(VkLayerTest, InvalidImageViewAspect) {
+TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
     VkResult err;
 
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "vkCreateImageView: Color image "
-                                         "formats must have ONLY the "
-                                         "VK_IMAGE_ASPECT_COLOR_BIT set");
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "used without first calling vkBindImageMemory");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
-    // Create an image and try to create a view with an invalid aspectMask
+    // Create an image and try to create a view with no memory backing the image
     VkImage image;
 
     const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
@@ -9921,6 +14943,7 @@
     image_create_info.extent.height = tex_height;
     image_create_info.extent.depth = 1;
     image_create_info.mipLevels = 1;
+    image_create_info.arrayLayers = 1;
     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
@@ -9934,6 +14957,46 @@
     image_view_create_info.image = image;
     image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
     image_view_create_info.format = tex_format;
+    image_view_create_info.subresourceRange.layerCount = 1;
+    image_view_create_info.subresourceRange.baseMipLevel = 0;
+    image_view_create_info.subresourceRange.levelCount = 1;
+    image_view_create_info.subresourceRange.aspectMask =
+        VK_IMAGE_ASPECT_COLOR_BIT;
+
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL,
+                            &view);
+
+    m_errorMonitor->VerifyFound();
+    vkDestroyImage(m_device->device(), image, NULL);
+    // If last error is success, it still created the view, so delete it.
+    if (err == VK_SUCCESS) {
+        vkDestroyImageView(m_device->device(), view, NULL);
+    }
+
+}
+
+TEST_F(VkLayerTest, InvalidImageViewAspect) {
+    TEST_DESCRIPTION(
+        "Create an image and try to create a view with an invalid aspectMask");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "vkCreateImageView: Color image "
+                                         "formats must have ONLY the "
+                                         "VK_IMAGE_ASPECT_COLOR_BIT set");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
+    VkImageObj image(m_device);
+    image.init(32, 32, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT,
+               VK_IMAGE_TILING_LINEAR, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageViewCreateInfo image_view_create_info = {};
+    image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_view_create_info.image = image.handle();
+    image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    image_view_create_info.format = tex_format;
     image_view_create_info.subresourceRange.baseMipLevel = 0;
     image_view_create_info.subresourceRange.levelCount = 1;
     // Cause an error by setting an invalid image aspect
@@ -9941,8 +15004,7 @@
         VK_IMAGE_ASPECT_METADATA_BIT;
 
     VkImageView view;
-    err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL,
-                            &view);
+    vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
 
     m_errorMonitor->VerifyFound();
 }
@@ -11096,7 +16158,7 @@
     VkImage image_bad;
     VkImage image_good;
     // One bad format and one good format for Color attachment
-    const VkFormat tex_format_bad = VK_FORMAT_D32_SFLOAT_S8_UINT;
+    const VkFormat tex_format_bad = VK_FORMAT_D24_UNORM_S8_UINT;
     const VkFormat tex_format_good = VK_FORMAT_B8G8R8A8_UNORM;
     const int32_t tex_width = 32;
     const int32_t tex_height = 32;
@@ -11220,6 +16282,17 @@
 
     m_errorMonitor->VerifyFound();
 
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "vkCmdClearColorImage called with "
+                                         "image created without "
+                                         "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
+
+    vkCmdClearColorImage(m_commandBuffer->GetBufferHandle(), ds_image.handle(),
+                         VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
+                         &color_range);
+
+    m_errorMonitor->VerifyFound();
+
     // Call CmdClearDepthStencilImage with color image
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -11234,6 +16307,155 @@
 }
 #endif // IMAGE_TESTS
 
+#if defined(ANDROID) && defined(VALIDATION_APK)
+static bool initialized = false;
+static bool active = false;
+
+// Convert Intents to argv
+// Ported from Hologram sample, only difference is flexible key
+std::vector<std::string> get_args(android_app &app, const char* intent_extra_data_key)
+{
+    std::vector<std::string> args;
+    JavaVM &vm = *app.activity->vm;
+    JNIEnv *p_env;
+    if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK)
+        return args;
+
+    JNIEnv &env = *p_env;
+    jobject activity = app.activity->clazz;
+    jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity),
+            "getIntent", "()Landroid/content/Intent;");
+    jobject intent = env.CallObjectMethod(activity, get_intent_method);
+    jmethodID get_string_extra_method = env.GetMethodID(env.GetObjectClass(intent),
+            "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
+    jvalue get_string_extra_args;
+    get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
+    jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent,
+            get_string_extra_method, &get_string_extra_args));
+
+    std::string args_str;
+    if (extra_str) {
+        const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
+        args_str = extra_utf;
+        env.ReleaseStringUTFChars(extra_str, extra_utf);
+        env.DeleteLocalRef(extra_str);
+    }
+
+    env.DeleteLocalRef(get_string_extra_args.l);
+    env.DeleteLocalRef(intent);
+    vm.DetachCurrentThread();
+
+    // split args_str
+    std::stringstream ss(args_str);
+    std::string arg;
+    while (std::getline(ss, arg, ' ')) {
+        if (!arg.empty())
+            args.push_back(arg);
+    }
+
+    return args;
+}
+
+
+static int32_t processInput(struct android_app* app, AInputEvent* event) {
+    return 0;
+}
+
+static void processCommand(struct android_app* app, int32_t cmd) {
+    switch(cmd) {
+        case APP_CMD_INIT_WINDOW: {
+            if (app->window) {
+                initialized = true;
+            }
+            break;
+        }
+        case APP_CMD_GAINED_FOCUS: {
+            active = true;
+            break;
+        }
+        case APP_CMD_LOST_FOCUS: {
+            active = false;
+            break;
+        }
+    }
+}
+
+void android_main(struct android_app *app)
+{
+    app_dummy();
+
+    const char* appTag = "VulkanLayerValidationTests";
+
+    int vulkanSupport = InitVulkan();
+    if (vulkanSupport == 0) {
+        __android_log_print(ANDROID_LOG_INFO, appTag, "==== FAILED ==== No Vulkan support found");
+        return;
+    }
+
+    app->onAppCmd = processCommand;
+    app->onInputEvent = processInput;
+
+    while(1) {
+        int events;
+        struct android_poll_source* source;
+        while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void**)&source) >= 0) {
+            if (source) {
+                source->process(app, source);
+            }
+
+            if (app->destroyRequested != 0) {
+                VkTestFramework::Finish();
+                return;
+            }
+        }
+
+        if (initialized && active) {
+          // Use the following key to send arguments to gtest, i.e.
+          // --es args "--gtest_filter=-VkLayerTest.foo"
+          const char key[] = "args";
+          std::vector<std::string> args = get_args(*app, key);
+
+          std::string filter = "";
+          if (args.size() > 0) {
+              __android_log_print(ANDROID_LOG_INFO, appTag, "Intent args = %s", args[0].c_str());
+              filter += args[0];
+          } else {
+              __android_log_print(ANDROID_LOG_INFO, appTag, "No Intent args detected");
+          }
+
+          int argc = 2;
+          char *argv[] = { (char*)"foo", (char*)filter.c_str() };
+           __android_log_print(ANDROID_LOG_DEBUG, appTag, "filter = %s", argv[1]);
+
+           // Route output to files until we can override the gtest output
+           freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/out.txt", "w", stdout);
+           freopen("/sdcard/Android/data/com.example.VulkanLayerValidationTests/files/err.txt", "w", stderr);
+
+           ::testing::InitGoogleTest(&argc, argv);
+           VkTestFramework::InitArgs(&argc, argv);
+           ::testing::AddGlobalTestEnvironment(new TestEnvironment);
+
+           int result = RUN_ALL_TESTS();
+
+           if (result != 0) {
+               __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests FAILED ====");
+           } else {
+               __android_log_print(ANDROID_LOG_INFO, appTag, "==== Tests PASSED ====");
+           }
+
+           VkTestFramework::Finish();
+
+           fclose(stdout);
+           fclose(stderr);
+
+           ANativeActivity_finish(app->activity);
+
+           return;
+        }
+    }
+}
+#endif
+
 int main(int argc, char **argv) {
     int result;
 
diff --git a/tests/layers/CMakeLists.txt b/tests/layers/CMakeLists.txt
new file mode 100644
index 0000000..87d7793
--- /dev/null
+++ b/tests/layers/CMakeLists.txt
@@ -0,0 +1,86 @@
+cmake_minimum_required (VERSION 2.8.11)
+
+set(LAYER_JSON_FILES
+    VkLayer_wrap_objects
+    )
+
+set(VK_LAYER_RPATH /usr/lib/x86_64-linux-gnu/vulkan/layer:/usr/lib/i386-linux-gnu/vulkan/layer)
+set(CMAKE_INSTALL_RPATH ${VK_LAYER_RPATH})
+
+if (WIN32)
+    if (NOT (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR))
+        foreach (config_file ${LAYER_JSON_FILES})
+            FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/windows/${config_file}.json src_json)
+            if (CMAKE_GENERATOR MATCHES "^Visual Studio.*")
+                FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>/${config_file}.json dst_json)
+            else()
+                FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/${config_file}.json dst_json)
+            endif()
+            add_custom_target(${config_file}-json ALL
+                COMMAND copy ${src_json} ${dst_json}
+                VERBATIM
+                )
+        endforeach(config_file)
+    endif()
+else()
+    # extra setup for out-of-tree builds
+    if (NOT (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR))
+        foreach (config_file ${LAYER_JSON_FILES})
+            add_custom_target(${config_file}-json ALL
+                COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/linux/${config_file}.json
+                VERBATIM
+                )
+        endforeach(config_file)
+    endif()
+endif()
+
+if (WIN32)
+    macro(add_vk_layer target)
+    add_custom_command(OUTPUT VkLayer_${target}.def
+        COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/vk-generate.py ${DisplayServer} win-def-file VkLayer_${target} layer > VkLayer_${target}.def
+        DEPENDS ${PROJECT_SOURCE_DIR}/vk-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py
+    )
+    add_library(VkLayer_${target} SHARED ${ARGN} VkLayer_${target}.def)
+    add_dependencies(VkLayer_${target} generate_vk_layer_helpers)
+    set_target_properties(VkLayer_${target} PROPERTIES LINK_FLAGS "/DEF:${CMAKE_CURRENT_BINARY_DIR}/VkLayer_${target}.def")
+    endmacro()
+else()
+    macro(add_vk_layer target)
+    add_library(VkLayer_${target} SHARED ${ARGN})
+    add_dependencies(VkLayer_${target} generate_vk_layer_helpers)
+    set_target_properties(VkLayer_${target} PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic")
+    install(TARGETS VkLayer_${target} DESTINATION ${PROJECT_BINARY_DIR}/install_staging)
+    endmacro()
+endif()
+
+include_directories(
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../layers
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../loader
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../include/vulkan
+    ${CMAKE_CURRENT_BINARY_DIR}/../../layers
+)
+
+if (WIN32)
+    set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D_CRT_SECURE_NO_WARNINGS")
+    set (CMAKE_C_FLAGS_RELEASE   "${CMAKE_C_FLAGS_RELEASE} -D_CRT_SECURE_NO_WARNINGS")
+    set (CMAKE_CXX_FLAGS_DEBUG   "${CMAKE_CXX_FLAGS_DEBUG} -D_CRT_SECURE_NO_WARNINGS /bigobj")
+    set (CMAKE_C_FLAGS_DEBUG     "${CMAKE_C_FLAGS_DEBUG} -D_CRT_SECURE_NO_WARNINGS /bigobj")
+else()
+    set (CMAKE_CXX_FLAGS "-std=c++11")
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpointer-arith")
+    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
+endif()
+
+add_custom_command(OUTPUT vk_dispatch_table_helper.h
+    COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/vk-generate.py ${DisplayServer} dispatch-table-ops layer > vk_dispatch_table_helper.h
+    DEPENDS ${PROJECT_SOURCE_DIR}/vk-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py)
+
+set (WRAP_SRCS
+       wrap_objects.cpp
+	   ${CMAKE_CURRENT_SOURCE_DIR}/../../layers/vk_layer_table.cpp
+	   ${CMAKE_CURRENT_SOURCE_DIR}/../../layers/vk_layer_extension_utils.cpp
+	   )
+add_vk_layer(wrap_objects ${WRAP_SRCS})
+
+
diff --git a/tests/layers/linux/VkLayer_wrap_objects.json b/tests/layers/linux/VkLayer_wrap_objects.json
new file mode 100644
index 0000000..7ea6f5a
--- /dev/null
+++ b/tests/layers/linux/VkLayer_wrap_objects.json
@@ -0,0 +1,11 @@
+{
+    "file_format_version" : "1.0.0",
+    "layer" : {
+        "name": "VK_LAYER_LUNARG_wrap_objects",
+        "type": "GLOBAL",
+        "library_path": "./libVkLayer_wrap_objects.so",
+        "api_version": "1.0.11",
+        "implementation_version": "1",
+        "description": "LunarG Dispatchable Object Wrapping Layer"
+    }
+}
diff --git a/tests/layers/windows/VkLayer_wrap_objects.json b/tests/layers/windows/VkLayer_wrap_objects.json
new file mode 100644
index 0000000..bf801a5
--- /dev/null
+++ b/tests/layers/windows/VkLayer_wrap_objects.json
@@ -0,0 +1,11 @@
+{
+    "file_format_version" : "1.0.0",
+    "layer" : {
+        "name": "VK_LAYER_LUNARG_wrap_objects",
+        "type": "GLOBAL",
+        "library_path": ".\\VkLayer_wrap_objects.dll",
+        "api_version": "1.0.11",
+        "implementation_version": "1",
+        "description": "LunarG Dispatchable Object Wrapping Layer"
+    }
+}
diff --git a/tests/layers/wrap_objects.cpp b/tests/layers/wrap_objects.cpp
new file mode 100644
index 0000000..9f7867c
--- /dev/null
+++ b/tests/layers/wrap_objects.cpp
@@ -0,0 +1,1604 @@
+/*
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ *
+ * Licensed under the Apache 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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: Jon Ashburn <jon@lunarg.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "vk_loader_platform.h"
+#include "vulkan/vk_layer.h"
+#include "vk_dispatch_table_helper.h"
+#include "vk_layer_extension_utils.h"
+#include "vk_layer_utils.h"
+#include "wrap_objects.h"
+
+namespace wrap_objects {
+
+static const VkLayerProperties global_layer = {
+    "VK_LAYER_LUNARG_wrap_objects", VK_LAYER_API_VERSION, 1, "LunarG Test Layer",
+};
+
+//TODO Add wrapping of Vkdevice, Vkqueue, VkcommandBuffer
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
+{
+    VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+    if (fpCreateInstance == NULL) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+    // Advance the link info for the next element on the chain
+    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+    VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+    if (result != VK_SUCCESS) {
+        return result;
+    }
+    auto inst = new wrapped_inst_obj;
+    if (!inst)
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    memset(inst, 0, sizeof(*inst));
+    inst->obj = (*pInstance);
+    *pInstance = reinterpret_cast<VkInstance> (inst);
+    // store the loader callback for initializing created dispatchable objects
+    chain_info = get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK);
+    if (chain_info) {
+        inst->pfn_inst_init = chain_info->u.pfnSetInstanceLoaderData;
+        result = inst->pfn_inst_init(inst->obj, reinterpret_cast<void *> (inst));
+        if (VK_SUCCESS != result)
+            return result;
+    } else {
+        inst->pfn_inst_init = NULL;
+        inst->loader_disp = *(reinterpret_cast<VkLayerInstanceDispatchTable **> (*pInstance));
+    }
+    layer_init_instance_dispatch_table(*pInstance, &inst->layer_disp, fpGetInstanceProcAddr);
+
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
+{
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    VkLayerInstanceDispatchTable *pDisp  =  &inst->layer_disp;
+    pDisp->DestroyInstance(vk_inst, pAllocator);
+    if (inst->ptr_phys_devs)
+        delete[] inst->ptr_phys_devs;
+    delete inst;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
+{
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    VkResult result = inst->layer_disp.EnumeratePhysicalDevices(vk_inst, pPhysicalDeviceCount, pPhysicalDevices);
+
+    if (VK_SUCCESS != result)
+        return result;
+
+    if (pPhysicalDevices != NULL) {
+        assert(pPhysicalDeviceCount);
+        auto phys_devs = new wrapped_phys_dev_obj[*pPhysicalDeviceCount];
+        if (!phys_devs)
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        if (inst->ptr_phys_devs)
+            delete[] inst->ptr_phys_devs;
+        inst->ptr_phys_devs = phys_devs;
+        for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
+            if (inst->pfn_inst_init == NULL) {
+                phys_devs[i].loader_disp = *(reinterpret_cast<VkLayerInstanceDispatchTable **> (pPhysicalDevices[i]));
+            } else {
+                result = inst->pfn_inst_init(vk_inst, reinterpret_cast<void *> (&phys_devs[i]));
+                if (VK_SUCCESS != result)
+                    return result;
+
+            }
+            phys_devs[i].obj = reinterpret_cast<void *> (pPhysicalDevices[i]);
+            phys_devs[i].inst = inst;
+            pPhysicalDevices[i] = reinterpret_cast<VkPhysicalDevice> (&phys_devs[i]);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    phys_dev->inst->layer_disp.GetPhysicalDeviceFeatures(vk_phys_dev, pFeatures);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    phys_dev->inst->layer_disp.GetPhysicalDeviceFormatProperties(vk_phys_dev, format, pFormatProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkResult result = phys_dev->inst->layer_disp.GetPhysicalDeviceImageFormatProperties(vk_phys_dev, format, type, tiling, usage, flags, pImageFormatProperties);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    phys_dev->inst->layer_disp.GetPhysicalDeviceProperties(vk_phys_dev, pProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    phys_dev->inst->layer_disp.GetPhysicalDeviceQueueFamilyProperties(vk_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    phys_dev->inst->layer_disp.GetPhysicalDeviceMemoryProperties(vk_phys_dev, pMemoryProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
+    if (fpCreateDevice == NULL) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+    // Advance the link info for the next element on the chain
+    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+    VkResult result = fpCreateDevice(vk_phys_dev, pCreateInfo, pAllocator, pDevice);
+    if (result != VK_SUCCESS) {
+        return result;
+    }
+    initDeviceTable(*pDevice, fpGetDeviceProcAddr);
+
+#if 0 // TODO add once device is wrapped
+    // store the loader callback for initializing created dispatchable objects
+    chain_info = get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK);
+    if (chain_info) {
+        dev->pfn_dev_init = chain_info->u.pfnSetDeviceLoaderData;
+    } else {
+        dev->pfn_dev_init = NULL;
+    }
+#endif
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
+{
+    dispatch_key key = get_dispatch_key(device);
+    VkLayerDispatchTable *pDisp  =  device_dispatch_table(device);
+    pDisp->DestroyDevice(device, pAllocator);
+    destroy_device_dispatch_table(key);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+
+    if (pLayerName && !strcmp(pLayerName, global_layer.layerName))
+        return util_GetExtensionProperties(0, nullptr, pPropertyCount, pProperties);
+
+    return phys_dev->inst->layer_disp.EnumerateDeviceExtensionProperties(vk_phys_dev, pLayerName, pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue)
+{
+    device_dispatch_table(device)->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence)
+{
+    VkResult result = device_dispatch_table(queue)->QueueSubmit(queue, submitCount, pSubmits, fence);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue)
+{
+    VkResult result = device_dispatch_table(queue)->QueueWaitIdle(queue);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device)
+{
+    VkResult result = device_dispatch_table(device)->DeviceWaitIdle(device);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory)
+{
+    VkResult result = device_dispatch_table(device)->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->FreeMemory(device, memory, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
+{
+    VkResult result = device_dispatch_table(device)->MapMemory(device, memory, offset, size, flags, ppData);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(VkDevice device, VkDeviceMemory memory)
+{
+    device_dispatch_table(device)->UnmapMemory(device, memory);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges)
+{
+    VkResult result = device_dispatch_table(device)->FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
+    return result;
+}
+
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges)
+{
+    VkResult result = device_dispatch_table(device)->InvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes)
+{
+    device_dispatch_table(device)->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset)
+{
+    VkResult result = device_dispatch_table(device)->BindBufferMemory(device, buffer, memory, memoryOffset);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset)
+{
+    VkResult result = device_dispatch_table(device)->BindImageMemory(device, image, memory, memoryOffset);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements)
+{
+    device_dispatch_table(device)->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements)
+{
+    device_dispatch_table(device)->GetImageMemoryRequirements(device, image, pMemoryRequirements);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
+{
+    device_dispatch_table(device)->GetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    phys_dev->inst->layer_disp.GetPhysicalDeviceSparseImageFormatProperties(vk_phys_dev, format, type, samples, usage, tiling, pPropertyCount, pProperties);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence)
+{
+    VkResult result = device_dispatch_table(queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence)
+{
+    VkResult result = device_dispatch_table(device)->CreateFence(device, pCreateInfo, pAllocator, pFence);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyFence(device, fence, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences)
+{
+    VkResult result = device_dispatch_table(device)->ResetFences(device, fenceCount, pFences);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus(VkDevice device, VkFence fence)
+{
+    VkResult result = device_dispatch_table(device)->GetFenceStatus(device, fence);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout)
+{
+    VkResult result = device_dispatch_table(device)->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore)
+{
+    VkResult result = device_dispatch_table(device)->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroySemaphore(device, semaphore, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent)
+{
+    VkResult result = device_dispatch_table(device)->CreateEvent(device, pCreateInfo, pAllocator, pEvent);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyEvent(device, event, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus(VkDevice device, VkEvent event)
+{
+    VkResult result = device_dispatch_table(device)->GetEventStatus(device, event);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(VkDevice device, VkEvent event)
+{
+    VkResult result = device_dispatch_table(device)->SetEvent(device, event);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent(VkDevice device, VkEvent event)
+{
+    VkResult result = device_dispatch_table(device)->ResetEvent(device, event);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool)
+{
+    VkResult result = device_dispatch_table(device)->CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyQueryPool(device, queryPool, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags)
+{
+    VkResult result = device_dispatch_table(device)->GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer)
+{
+    VkResult result = device_dispatch_table(device)->CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyBuffer(device, buffer, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView)
+{
+    VkResult result = device_dispatch_table(device)->CreateBufferView(device, pCreateInfo, pAllocator, pView);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyBufferView(device, bufferView, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage)
+{
+    VkResult result = device_dispatch_table(device)->CreateImage(device, pCreateInfo, pAllocator, pImage);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyImage(device, image, pAllocator);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout)
+{
+    device_dispatch_table(device)->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView)
+{
+    VkResult result = device_dispatch_table(device)->CreateImageView(device, pCreateInfo, pAllocator, pView);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyImageView(device, imageView, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule)
+{
+    VkResult result = device_dispatch_table(device)->CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyShaderModule(device, shaderModule, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache)
+{
+    VkResult result = device_dispatch_table(device)->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyPipelineCache(device, pipelineCache, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData)
+{
+    VkResult result = device_dispatch_table(device)->GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches)
+{
+    VkResult result = device_dispatch_table(device)->MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
+{
+    VkResult result = device_dispatch_table(device)->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
+{
+    VkResult result = device_dispatch_table(device)->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyPipeline(device, pipeline, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout)
+{
+    VkResult result = device_dispatch_table(device)->CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler)
+{
+    VkResult result = device_dispatch_table(device)->CreateSampler(device, pCreateInfo, pAllocator, pSampler);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroySampler(device, sampler, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout)
+{
+    VkResult result = device_dispatch_table(device)->CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool)
+{
+    VkResult result = device_dispatch_table(device)->CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags)
+{
+    VkResult result = device_dispatch_table(device)->ResetDescriptorPool(device, descriptorPool, flags);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
+{
+    VkResult result = device_dispatch_table(device)->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets)
+{
+    VkResult result = device_dispatch_table(device)->FreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies)
+{
+    device_dispatch_table(device)->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer)
+{
+    VkResult result = device_dispatch_table(device)->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyFramebuffer(device, framebuffer, pAllocator);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass)
+{
+    VkResult result = device_dispatch_table(device)->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyRenderPass(device, renderPass, pAllocator);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity)
+{
+    device_dispatch_table(device)->GetRenderAreaGranularity(device, renderPass, pGranularity);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool)
+{
+    VkResult result = device_dispatch_table(device)->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
+    return result;
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroyCommandPool(device, commandPool, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags)
+{
+    VkResult result = device_dispatch_table(device)->ResetCommandPool(device, commandPool, flags);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
+{
+    VkResult result = device_dispatch_table(device)->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
+{
+    device_dispatch_table(device)->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo)
+{
+    VkResult result = device_dispatch_table(commandBuffer)->BeginCommandBuffer(commandBuffer, pBeginInfo);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer)
+{
+    VkResult result = device_dispatch_table(commandBuffer)->EndCommandBuffer(commandBuffer);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags)
+{
+    VkResult result = device_dispatch_table(commandBuffer)->ResetCommandBuffer(commandBuffer, flags);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
+{
+    device_dispatch_table(commandBuffer)->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
+{
+    device_dispatch_table(commandBuffer)->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
+{
+    device_dispatch_table(commandBuffer)->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
+{
+    device_dispatch_table(commandBuffer)->CmdSetLineWidth(commandBuffer, lineWidth);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
+{
+    device_dispatch_table(commandBuffer)->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4])
+{
+    device_dispatch_table(commandBuffer)->CmdSetBlendConstants(commandBuffer, blendConstants);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds)
+{
+    device_dispatch_table(commandBuffer)->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask)
+{
+    device_dispatch_table(commandBuffer)->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask)
+{
+    device_dispatch_table(commandBuffer)->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference)
+{
+    device_dispatch_table(commandBuffer)->CmdSetStencilReference(commandBuffer, faceMask, reference);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
+{
+    device_dispatch_table(commandBuffer)->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
+{
+    device_dispatch_table(commandBuffer)->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets)
+{
+    device_dispatch_table(commandBuffer)->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
+{
+    device_dispatch_table(commandBuffer)->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
+{
+    device_dispatch_table(commandBuffer)->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
+{
+    device_dispatch_table(commandBuffer)->CmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
+{
+    device_dispatch_table(commandBuffer)->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z)
+{
+    device_dispatch_table(commandBuffer)->CmdDispatch(commandBuffer, x, y, z);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset)
+{
+    device_dispatch_table(commandBuffer)->CmdDispatchIndirect(commandBuffer, buffer, offset);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
+{
+    device_dispatch_table(commandBuffer)->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions)
+{
+    device_dispatch_table(commandBuffer)->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter)
+{
+    device_dispatch_table(commandBuffer)->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions)
+{
+    device_dispatch_table(commandBuffer)->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions)
+{
+    device_dispatch_table(commandBuffer)->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t* pData)
+{
+    device_dispatch_table(commandBuffer)->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data)
+{
+    device_dispatch_table(commandBuffer)->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
+{
+    device_dispatch_table(commandBuffer)->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
+{
+    device_dispatch_table(commandBuffer)->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects)
+{
+    device_dispatch_table(commandBuffer)->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions)
+{
+    device_dispatch_table(commandBuffer)->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
+{
+    device_dispatch_table(commandBuffer)->CmdSetEvent(commandBuffer, event, stageMask);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
+{
+    device_dispatch_table(commandBuffer)->CmdResetEvent(commandBuffer, event, stageMask);
+}
+
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
+{
+    device_dispatch_table(commandBuffer)->CmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers)
+{
+    device_dispatch_table(commandBuffer)->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
+{
+    device_dispatch_table(commandBuffer)->CmdBeginQuery(commandBuffer, queryPool, query, flags);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query)
+{
+    device_dispatch_table(commandBuffer)->CmdEndQuery(commandBuffer, queryPool, query);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount)
+{
+    device_dispatch_table(commandBuffer)->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
+{
+    device_dispatch_table(commandBuffer)->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags)
+{
+    device_dispatch_table(commandBuffer)->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues)
+{
+    device_dispatch_table(commandBuffer)->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents)
+{
+    device_dispatch_table(commandBuffer)->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
+{
+    device_dispatch_table(commandBuffer)->CmdNextSubpass(commandBuffer, contents);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(VkCommandBuffer commandBuffer)
+{
+    device_dispatch_table(commandBuffer)->CmdEndRenderPass(commandBuffer);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
+{
+    device_dispatch_table(commandBuffer)->CmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator)
+{
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    inst->layer_disp.DestroySurfaceKHR(vk_inst, surface, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkResult result = phys_dev->inst->layer_disp.GetPhysicalDeviceSurfaceSupportKHR(vk_phys_dev, queueFamilyIndex, surface, pSupported);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkResult result = phys_dev->inst->layer_disp.GetPhysicalDeviceSurfaceCapabilitiesKHR(vk_phys_dev, surface, pSurfaceCapabilities);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkResult result = phys_dev->inst->layer_disp.GetPhysicalDeviceSurfaceFormatsKHR(vk_phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats);
+    return result;
+}
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkResult result = phys_dev->inst->layer_disp.GetPhysicalDeviceSurfacePresentModesKHR(vk_phys_dev, surface, pPresentModeCount, pPresentModes);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain)
+{
+    VkResult result = device_dispatch_table(device)->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator)
+{
+    device_dispatch_table(device)->DestroySwapchainKHR(device, swapchain, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages)
+{
+    VkResult result = device_dispatch_table(device)->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex)
+{
+    VkResult result = device_dispatch_table(device)->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo)
+{
+    VkResult result = device_dispatch_table(queue)->QueuePresentKHR(queue, pPresentInfo);
+    return result;
+}
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+
+VKAPI_ATTR VkResult VKAPI_CALL
+vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+                        const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult result;
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    result = inst->layer_disp.CreateWin32SurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface);
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL
+vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex) {
+    VkBool32 result;
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    result = phys_dev->inst->layer_disp.GetPhysicalDeviceWin32PresentationSupportKHR(vk_phys_dev, queueFamilyIndex);
+    return result;
+}
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
+{
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    VkResult result = inst->layer_disp.CreateXcbSurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface);
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkBool32 result = phys_dev->inst->layer_disp.GetPhysicalDeviceXcbPresentationSupportKHR(vk_phys_dev, queueFamilyIndex, connection, visual_id);
+    return result;
+}
+#endif  // VK_USE_PLATFORM_XCB_KHR
+
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
+{
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    VkResult result = inst->layer_disp.CreateXlibSurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface);
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkBool32 result = phys_dev->inst->layer_disp.GetPhysicalDeviceXlibPresentationSupportKHR(vk_phys_dev, queueFamilyIndex, dpy, visualID);
+    return result;
+}
+#endif  // VK_USE_PLATFORM_XLIB_KHR
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
+{
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    VkResult result = inst->layer_disp.CreateWaylandSurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface);
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkBool32 result = phys_dev->inst->layer_disp.GetPhysicalDeviceWaylandPresentationSupportKHR(vk_phys_dev, queueFamilyIndex, display);
+    return result;
+}
+#endif  // VK_USE_PLATFORM_WAYLAND_KHR
+
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
+{
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    VkResult result = inst->layer_disp.CreateMirSurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface);
+    return result;
+}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection)
+{
+    wrapped_phys_dev_obj *phys_dev;
+    auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
+    VkBool32 result = phys_dev->inst->layer_disp.GetPhysicalDeviceMirPresentationSupportKHR(vk_phys_dev, queueFamilyIndex, connection);
+    return result;
+}
+#endif  // VK_USE_PLATFORM_MIR_KHR
+
+VKAPI_ATTR VkResult VKAPI_CALL
+vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+                             const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+
+    VkResult res = inst->layer_disp.CreateDebugReportCallbackEXT(vk_inst, pCreateInfo, pAllocator, pMsgCallback);
+    return res;
+}
+
+VKAPI_ATTR void VKAPI_CALL
+vkDestroyDebugReportCallbackEXT(VkInstance instance,
+                              VkDebugReportCallbackEXT msgCallback,
+                              const VkAllocationCallbacks *pAllocator) {
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    inst->layer_disp.DestroyDebugReportCallbackEXT(vk_inst, msgCallback, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL
+vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
+                      size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    inst->layer_disp.DebugReportMessageEXT(vk_inst, flags, objType, object, location, msgCode, pLayerPrefix,
+                                                            pMsg);
+}
+
+static inline PFN_vkVoidFunction layer_intercept_proc(const char *name)
+{
+    if (!name || name[0] != 'v' || name[1] != 'k')
+        return NULL;
+
+    name += 2;
+    if (!strcmp(name, "CreateInstance"))
+        return (PFN_vkVoidFunction) vkCreateInstance;
+    if (!strcmp(name, "DestroyInstance"))
+        return (PFN_vkVoidFunction) vkDestroyInstance;
+    if (!strcmp(name, "EnumeratePhysicalDevices"))
+        return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
+    if (!strcmp(name, "GetPhysicalDeviceFeatures"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceFeatures;
+    if (!strcmp(name, "GetPhysicalDeviceFormatProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceFormatProperties;
+    if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceImageFormatProperties;
+    if (!strcmp(name, "GetPhysicalDeviceProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceProperties;
+    if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceQueueFamilyProperties;
+    if (!strcmp(name, "GetPhysicalDeviceMemoryProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceMemoryProperties;
+    if (!strcmp(name, "CreateDevice"))
+        return (PFN_vkVoidFunction) vkCreateDevice;
+    if (!strcmp(name, "DestroyDevice"))
+        return (PFN_vkVoidFunction) vkDestroyDevice;
+    if (!strcmp(name, "GetDeviceQueue"))
+        return (PFN_vkVoidFunction) vkGetDeviceQueue;
+    if (!strcmp(name, "QueueSubmit"))
+        return (PFN_vkVoidFunction) vkQueueSubmit;
+    if (!strcmp(name, "QueueWaitIdle"))
+        return (PFN_vkVoidFunction) vkQueueWaitIdle;
+    if (!strcmp(name, "DeviceWaitIdle"))
+        return (PFN_vkVoidFunction) vkDeviceWaitIdle;
+    if (!strcmp(name, "AllocateMemory"))
+        return (PFN_vkVoidFunction) vkAllocateMemory;
+    if (!strcmp(name, "FreeMemory"))
+        return (PFN_vkVoidFunction) vkFreeMemory;
+    if (!strcmp(name, "MapMemory"))
+        return (PFN_vkVoidFunction) vkMapMemory;
+    if (!strcmp(name, "UnmapMemory"))
+        return (PFN_vkVoidFunction) vkUnmapMemory;
+    if (!strcmp(name, "FlushMappedMemoryRanges"))
+        return (PFN_vkVoidFunction) vkFlushMappedMemoryRanges;
+    if (!strcmp(name, "InvalidateMappedMemoryRanges"))
+        return (PFN_vkVoidFunction) vkInvalidateMappedMemoryRanges;
+    if (!strcmp(name, "GetDeviceMemoryCommitment"))
+        return (PFN_vkVoidFunction) vkGetDeviceMemoryCommitment;
+    if (!strcmp(name, "BindBufferMemory"))
+        return (PFN_vkVoidFunction) vkBindBufferMemory;
+    if (!strcmp(name, "BindImageMemory"))
+        return (PFN_vkVoidFunction) vkBindImageMemory;
+    if (!strcmp(name, "GetBufferMemoryRequirements"))
+        return (PFN_vkVoidFunction) vkGetBufferMemoryRequirements;
+    if (!strcmp(name, "GetImageMemoryRequirements"))
+        return (PFN_vkVoidFunction) vkGetImageMemoryRequirements;
+    if (!strcmp(name, "GetImageSparseMemoryRequirements"))
+        return (PFN_vkVoidFunction) vkGetImageSparseMemoryRequirements;
+    if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceSparseImageFormatProperties;
+    if (!strcmp(name, "QueueBindSparse"))
+        return (PFN_vkVoidFunction) vkQueueBindSparse;
+    if (!strcmp(name, "CreateFence"))
+        return (PFN_vkVoidFunction) vkCreateFence;
+    if (!strcmp(name, "DestroyFence"))
+        return (PFN_vkVoidFunction) vkDestroyFence;
+    if (!strcmp(name, "ResetFences"))
+        return (PFN_vkVoidFunction) vkResetFences;
+    if (!strcmp(name, "GetFenceStatus"))
+        return (PFN_vkVoidFunction) vkGetFenceStatus;
+    if (!strcmp(name, "WaitForFences"))
+        return (PFN_vkVoidFunction) vkWaitForFences;
+    if (!strcmp(name, "CreateSemaphore"))
+        return (PFN_vkVoidFunction) vkCreateSemaphore;
+    if (!strcmp(name, "DestroySemaphore"))
+        return (PFN_vkVoidFunction) vkDestroySemaphore;
+    if (!strcmp(name, "CreateEvent"))
+        return (PFN_vkVoidFunction) vkCreateEvent;
+    if (!strcmp(name, "DestroyEvent"))
+        return (PFN_vkVoidFunction) vkDestroyEvent;
+    if (!strcmp(name, "GetEventStatus"))
+        return (PFN_vkVoidFunction) vkGetEventStatus;
+    if (!strcmp(name, "SetEvent"))
+        return (PFN_vkVoidFunction) vkSetEvent;
+    if (!strcmp(name, "ResetEvent"))
+        return (PFN_vkVoidFunction) vkResetEvent;
+    if (!strcmp(name, "CreateQueryPool"))
+        return (PFN_vkVoidFunction) vkCreateQueryPool;
+    if (!strcmp(name, "DestroyQueryPool"))
+        return (PFN_vkVoidFunction) vkDestroyQueryPool;
+    if (!strcmp(name, "GetQueryPoolResults"))
+        return (PFN_vkVoidFunction) vkGetQueryPoolResults;
+    if (!strcmp(name, "CreateBuffer"))
+        return (PFN_vkVoidFunction) vkCreateBuffer;
+    if (!strcmp(name, "DestroyBuffer"))
+        return (PFN_vkVoidFunction) vkDestroyBuffer;
+    if (!strcmp(name, "CreateBufferView"))
+        return (PFN_vkVoidFunction) vkCreateBufferView;
+    if (!strcmp(name, "DestroyBufferView"))
+        return (PFN_vkVoidFunction) vkDestroyBufferView;
+    if (!strcmp(name, "CreateImage"))
+        return (PFN_vkVoidFunction) vkCreateImage;
+    if (!strcmp(name, "DestroyImage"))
+        return (PFN_vkVoidFunction) vkDestroyImage;
+    if (!strcmp(name, "GetImageSubresourceLayout"))
+        return (PFN_vkVoidFunction) vkGetImageSubresourceLayout;
+    if (!strcmp(name, "CreateImageView"))
+        return (PFN_vkVoidFunction) vkCreateImageView;
+    if (!strcmp(name, "DestroyImageView"))
+        return (PFN_vkVoidFunction) vkDestroyImageView;
+    if (!strcmp(name, "CreateShaderModule"))
+        return (PFN_vkVoidFunction) vkCreateShaderModule;
+    if (!strcmp(name, "DestroyShaderModule"))
+        return (PFN_vkVoidFunction) vkDestroyShaderModule;
+    if (!strcmp(name, "CreatePipelineCache"))
+        return (PFN_vkVoidFunction) vkCreatePipelineCache;
+    if (!strcmp(name, "DestroyPipelineCache"))
+        return (PFN_vkVoidFunction) vkDestroyPipelineCache;
+    if (!strcmp(name, "GetPipelineCacheData"))
+        return (PFN_vkVoidFunction) vkGetPipelineCacheData;
+    if (!strcmp(name, "MergePipelineCaches"))
+        return (PFN_vkVoidFunction) vkMergePipelineCaches;
+    if (!strcmp(name, "CreateGraphicsPipelines"))
+        return (PFN_vkVoidFunction) vkCreateGraphicsPipelines;
+    if (!strcmp(name, "CreateComputePipelines"))
+        return (PFN_vkVoidFunction) vkCreateComputePipelines;
+    if (!strcmp(name, "DestroyPipeline"))
+        return (PFN_vkVoidFunction) vkDestroyPipeline;
+    if (!strcmp(name, "CreatePipelineLayout"))
+        return (PFN_vkVoidFunction) vkCreatePipelineLayout;
+    if (!strcmp(name, "DestroyPipelineLayout"))
+        return (PFN_vkVoidFunction) vkDestroyPipelineLayout;
+    if (!strcmp(name, "CreateSampler"))
+        return (PFN_vkVoidFunction) vkCreateSampler;
+    if (!strcmp(name, "DestroySampler"))
+        return (PFN_vkVoidFunction) vkDestroySampler;
+    if (!strcmp(name, "CreateDescriptorSetLayout"))
+        return (PFN_vkVoidFunction) vkCreateDescriptorSetLayout;
+    if (!strcmp(name, "DestroyDescriptorSetLayout"))
+        return (PFN_vkVoidFunction) vkDestroyDescriptorSetLayout;
+    if (!strcmp(name, "CreateDescriptorPool"))
+        return (PFN_vkVoidFunction) vkCreateDescriptorPool;
+    if (!strcmp(name, "DestroyDescriptorPool"))
+        return (PFN_vkVoidFunction) vkDestroyDescriptorPool;
+    if (!strcmp(name, "ResetDescriptorPool"))
+        return (PFN_vkVoidFunction) vkResetDescriptorPool;
+    if (!strcmp(name, "AllocateDescriptorSets"))
+        return (PFN_vkVoidFunction) vkAllocateDescriptorSets;
+    if (!strcmp(name, "FreeDescriptorSets"))
+        return (PFN_vkVoidFunction) vkFreeDescriptorSets;
+    if (!strcmp(name, "UpdateDescriptorSets"))
+        return (PFN_vkVoidFunction) vkUpdateDescriptorSets;
+    if (!strcmp(name, "CreateFramebuffer"))
+        return (PFN_vkVoidFunction) vkCreateFramebuffer;
+    if (!strcmp(name, "DestroyFramebuffer"))
+        return (PFN_vkVoidFunction) vkDestroyFramebuffer;
+    if (!strcmp(name, "CreateRenderPass"))
+        return (PFN_vkVoidFunction) vkCreateRenderPass;
+    if (!strcmp(name, "DestroyRenderPass"))
+        return (PFN_vkVoidFunction) vkDestroyRenderPass;
+    if (!strcmp(name, "GetRenderAreaGranularity"))
+        return (PFN_vkVoidFunction) vkGetRenderAreaGranularity;
+    if (!strcmp(name, "CreateCommandPool"))
+        return (PFN_vkVoidFunction) vkCreateCommandPool;
+    if (!strcmp(name, "DestroyCommandPool"))
+        return (PFN_vkVoidFunction) vkDestroyCommandPool;
+    if (!strcmp(name, "ResetCommandPool"))
+        return (PFN_vkVoidFunction) vkResetCommandPool;
+    if (!strcmp(name, "AllocateCommandBuffers"))
+        return (PFN_vkVoidFunction) vkAllocateCommandBuffers;
+    if (!strcmp(name, "FreeCommandBuffers"))
+        return (PFN_vkVoidFunction) vkFreeCommandBuffers;
+    if (!strcmp(name, "BeginCommandBuffer"))
+        return (PFN_vkVoidFunction) vkBeginCommandBuffer;
+    if (!strcmp(name, "EndCommandBuffer"))
+        return (PFN_vkVoidFunction) vkEndCommandBuffer;
+    if (!strcmp(name, "ResetCommandBuffer"))
+        return (PFN_vkVoidFunction) vkResetCommandBuffer;
+    if (!strcmp(name, "CmdBindPipeline"))
+        return (PFN_vkVoidFunction) vkCmdBindPipeline;
+    if (!strcmp(name, "CmdSetViewport"))
+        return (PFN_vkVoidFunction) vkCmdSetViewport;
+    if (!strcmp(name, "CmdSetScissor"))
+        return (PFN_vkVoidFunction) vkCmdSetScissor;
+    if (!strcmp(name, "CmdSetLineWidth"))
+        return (PFN_vkVoidFunction) vkCmdSetLineWidth;
+    if (!strcmp(name, "CmdSetDepthBias"))
+        return (PFN_vkVoidFunction) vkCmdSetDepthBias;
+    if (!strcmp(name, "CmdSetBlendConstants"))
+        return (PFN_vkVoidFunction) vkCmdSetBlendConstants;
+    if (!strcmp(name, "CmdSetDepthBounds"))
+        return (PFN_vkVoidFunction) vkCmdSetDepthBounds;
+    if (!strcmp(name, "CmdSetStencilCompareMask"))
+        return (PFN_vkVoidFunction) vkCmdSetStencilCompareMask;
+    if (!strcmp(name, "CmdSetStencilWriteMask"))
+        return (PFN_vkVoidFunction) vkCmdSetStencilWriteMask;
+    if (!strcmp(name, "CmdSetStencilReference"))
+        return (PFN_vkVoidFunction) vkCmdSetStencilReference;
+    if (!strcmp(name, "CmdBindDescriptorSets"))
+        return (PFN_vkVoidFunction) vkCmdBindDescriptorSets;
+    if (!strcmp(name, "CmdBindIndexBuffer"))
+        return (PFN_vkVoidFunction) vkCmdBindIndexBuffer;
+    if (!strcmp(name, "CmdBindVertexBuffers"))
+        return (PFN_vkVoidFunction) vkCmdBindVertexBuffers;
+    if (!strcmp(name, "CmdDraw"))
+        return (PFN_vkVoidFunction) vkCmdDraw;
+    if (!strcmp(name, "CmdDrawIndexed"))
+        return (PFN_vkVoidFunction) vkCmdDrawIndexed;
+    if (!strcmp(name, "CmdDrawIndirect"))
+        return (PFN_vkVoidFunction) vkCmdDrawIndirect;
+    if (!strcmp(name, "CmdDrawIndexedIndirect"))
+        return (PFN_vkVoidFunction) vkCmdDrawIndexedIndirect;
+    if (!strcmp(name, "CmdDispatch"))
+        return (PFN_vkVoidFunction) vkCmdDispatch;
+    if (!strcmp(name, "CmdDispatchIndirect"))
+        return (PFN_vkVoidFunction) vkCmdDispatchIndirect;
+    if (!strcmp(name, "CmdCopyBuffer"))
+        return (PFN_vkVoidFunction) vkCmdCopyBuffer;
+    if (!strcmp(name, "CmdCopyImage"))
+        return (PFN_vkVoidFunction) vkCmdCopyImage;
+    if (!strcmp(name, "CmdBlitImage"))
+        return (PFN_vkVoidFunction) vkCmdBlitImage;
+    if (!strcmp(name, "CmdCopyBufferToImage"))
+        return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
+    if (!strcmp(name, "CmdCopyImageToBuffer"))
+        return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
+    if (!strcmp(name, "CmdUpdateBuffer"))
+        return (PFN_vkVoidFunction) vkCmdUpdateBuffer;
+    if (!strcmp(name, "CmdFillBuffer"))
+        return (PFN_vkVoidFunction) vkCmdFillBuffer;
+    if (!strcmp(name, "CmdClearColorImage"))
+        return (PFN_vkVoidFunction) vkCmdClearColorImage;
+    if (!strcmp(name, "CmdClearDepthStencilImage"))
+        return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
+    if (!strcmp(name, "CmdClearAttachments"))
+        return (PFN_vkVoidFunction) vkCmdClearAttachments;
+    if (!strcmp(name, "CmdResolveImage"))
+        return (PFN_vkVoidFunction) vkCmdResolveImage;
+    if (!strcmp(name, "CmdSetEvent"))
+        return (PFN_vkVoidFunction) vkCmdSetEvent;
+    if (!strcmp(name, "CmdResetEvent"))
+        return (PFN_vkVoidFunction) vkCmdResetEvent;
+    if (!strcmp(name, "CmdWaitEvents"))
+        return (PFN_vkVoidFunction) vkCmdWaitEvents;
+    if (!strcmp(name, "CmdPipelineBarrier"))
+        return (PFN_vkVoidFunction) vkCmdPipelineBarrier;
+    if (!strcmp(name, "CmdBeginQuery"))
+        return (PFN_vkVoidFunction) vkCmdBeginQuery;
+    if (!strcmp(name, "CmdEndQuery"))
+        return (PFN_vkVoidFunction) vkCmdEndQuery;
+    if (!strcmp(name, "CmdResetQueryPool"))
+        return (PFN_vkVoidFunction) vkCmdResetQueryPool;
+    if (!strcmp(name, "CmdWriteTimestamp"))
+        return (PFN_vkVoidFunction) vkCmdWriteTimestamp;
+    if (!strcmp(name, "CmdCopyQueryPoolResults"))
+        return (PFN_vkVoidFunction) vkCmdCopyQueryPoolResults;
+    if (!strcmp(name, "CmdPushConstants"))
+        return (PFN_vkVoidFunction) vkCmdPushConstants;
+    if (!strcmp(name, "CmdBeginRenderPass"))
+        return (PFN_vkVoidFunction) vkCmdBeginRenderPass;
+    if (!strcmp(name, "CmdNextSubpass"))
+        return (PFN_vkVoidFunction) vkCmdNextSubpass;
+    if (!strcmp(name, "CmdEndRenderPass"))
+        return (PFN_vkVoidFunction) vkCmdEndRenderPass;
+    if (!strcmp(name, "CmdExecuteCommands"))
+        return (PFN_vkVoidFunction) vkCmdExecuteCommands;
+
+    return NULL;
+}
+
+static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name)
+{
+    if (!name || name[0] != 'v' || name[1] != 'k')
+        return NULL;
+
+    name += 2;
+    if (!strcmp(name, "GetInstanceProcAddr"))
+        return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
+    if (!strcmp(name, "DestroyInstance"))
+        return (PFN_vkVoidFunction) vkDestroyInstance;
+    if (!strcmp(name, "EnumeratePhysicalDevices"))
+        return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
+    if (!strcmp(name, "GetPhysicalDeviceFeatures"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceFeatures;
+    if (!strcmp(name, "GetPhysicalDeviceFormatProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceFormatProperties;
+    if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceImageFormatProperties;
+    if (!strcmp(name, "GetPhysicalDeviceProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceProperties;
+    if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceQueueFamilyProperties;
+    if (!strcmp(name, "GetPhysicalDeviceMemoryProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceMemoryProperties;
+    if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties"))
+        return (PFN_vkVoidFunction) vkGetPhysicalDeviceSparseImageFormatProperties;
+    if (!strcmp(name, "EnumerateDeviceExtensionProperties"))
+        return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties;
+    return NULL;
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
+{
+    PFN_vkVoidFunction addr;
+
+
+    if (!strcmp("vkGetDeviceProcAddr", funcName)) {
+        return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
+    }
+
+    addr = layer_intercept_proc(funcName);
+    if (addr)
+        return addr;
+    if (device == VK_NULL_HANDLE) {
+        return NULL;
+    }
+
+    if (!strcmp("vkCreateSwapchainKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkCreateSwapchainKHR);
+    if (!strcmp("vkDestroySwapchainKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySwapchainKHR);
+    if (!strcmp("vkGetSwapchainImagesKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetSwapchainImagesKHR);
+    if (!strcmp("vkAcquireNextImageKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkAcquireNextImageKHR);
+    if (!strcmp("vkQueuePresentKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkQueuePresentKHR);
+
+    VkLayerDispatchTable *pDisp =  device_dispatch_table(device);
+    if (pDisp->GetDeviceProcAddr == NULL)
+    {
+        return NULL;
+    }
+
+    return pDisp->GetDeviceProcAddr(device, funcName);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
+{
+    PFN_vkVoidFunction addr;
+
+    if (!strcmp(funcName, "vkCreateInstance"))
+        return (PFN_vkVoidFunction) vkCreateInstance;
+    if (!strcmp(funcName, "vkCreateDevice"))
+        return (PFN_vkVoidFunction) vkCreateDevice;
+
+    if (instance == VK_NULL_HANDLE) {
+        return NULL;
+    }
+
+    addr = layer_intercept_instance_proc(funcName);
+    if (addr)
+        return addr;
+
+    wrapped_inst_obj *inst;
+    auto vk_inst = unwrap_instance(instance, &inst);
+    VkLayerInstanceDispatchTable* pTable = &inst->layer_disp;
+
+    // EXT_debug_report
+    if (!strcmp(funcName, "vkCreateDebugReportCallbackEXT"))
+        return (PFN_vkVoidFunction)vkCreateDebugReportCallbackEXT;
+    if (!strcmp(funcName, "vkDestroyDebugReportCallbackEXT"))
+        return (PFN_vkVoidFunction)vkDestroyDebugReportCallbackEXT;
+    if (!strcmp(funcName, "vkDebugReportMessageEXT"))
+        return (PFN_vkVoidFunction)vkDebugReportMessageEXT;
+
+    //KHR_surface
+    if (!strcmp("vkDestroySurfaceKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySurfaceKHR);
+    if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceSupportKHR);
+    if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
+    if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceFormatsKHR);
+    if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfacePresentModesKHR);
+
+    // KHR_XXX_surface
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    if (!strcmp("vkCreateXcbSurfaceKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkCreateXcbSurfaceKHR);
+    if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceXcbPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    if (!strcmp("vkCreateXlibSurfaceKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkCreateXlibSurfaceKHR);
+    if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceXlibPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    if (!strcmp("vkCreateMirSurfaceKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkCreateMirSurfaceKHR);
+    if (!strcmp("vkGetPhysicalDeviceMirPresentationSupportKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceMirPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_MIR_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    if (!strcmp("vkCreateWaylandSurfaceKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkCreateWaylandSurfaceKHR);
+    if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceWaylandPresentationSupportKHR);
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    if (!strcmp("vkCreateWin32SurfaceKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkCreateWin32SurfaceKHR);
+    if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", funcName))
+        return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceWin32PresentationSupportKHR);
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+    if (pTable->GetInstanceProcAddr == NULL)
+        return NULL;
+    return pTable->GetInstanceProcAddr(instance, funcName);
+}
+
+} // namespace wrap_objects
+
+// loader-layer interface v0, just wrappers since there is only a layer
+VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName) {
+    return wrap_objects::vkGetInstanceProcAddr(instance, funcName);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName) {
+    return wrap_objects::vkGetDeviceProcAddr(device, funcName);
+}
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
+vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
+    assert(0); // TODO return wrap_objects::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
+    return VK_SUCCESS;
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
+vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    assert(0); // TODO return wrap_objects::EnumerateInstanceLayerProperties(pCount, pProperties);
+    return VK_SUCCESS;
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
+vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    assert(0); // TODO return wrap_objects::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
+    return VK_SUCCESS;
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
+    const char *pLayerName, uint32_t *pCount,
+    VkExtensionProperties *pProperties) {
+    // the layer command handles VK_NULL_HANDLE just fine internally
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return wrap_objects::vkEnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
+}
diff --git a/tests/layers/wrap_objects.h b/tests/layers/wrap_objects.h
new file mode 100644
index 0000000..9e42226
--- /dev/null
+++ b/tests/layers/wrap_objects.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright (C) 2015-2016 Valve Corporation
+ * Copyright (C) 2015-2016 LunarG, Inc.
+ *
+ * Licensed under the Apache 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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: Jon Ashburn <jon@lunarg.com>
+ *
+ */
+
+#pragma once
+#include <unordered_map>
+#include "vulkan/vk_layer.h"
+
+struct wrapped_phys_dev_obj {
+    VkLayerInstanceDispatchTable *loader_disp;
+    struct wrapped_inst_obj *inst;  // parent instance object
+    void *obj;
+};
+
+struct wrapped_inst_obj {
+    VkLayerInstanceDispatchTable *loader_disp;
+    VkLayerInstanceDispatchTable layer_disp;    //this layer's dispatch table
+    PFN_vkSetInstanceLoaderData pfn_inst_init;
+    struct wrapped_phys_dev_obj *ptr_phys_devs; // any enumerated phys devs
+    VkInstance obj;
+};
+
+struct wrapped_dev_obj {
+    VkLayerDispatchTable *disp;
+    VkLayerInstanceDispatchTable *layer_disp;  // TODO use this
+    PFN_vkSetDeviceLoaderData pfn_dev_init;  //TODO use this
+    void *obj;
+};
+
+static inline VkInstance unwrap_instance(const VkInstance instance,  wrapped_inst_obj **inst) {
+   *inst = reinterpret_cast<wrapped_inst_obj *> (instance);
+   return (*inst)->obj;
+}
+
+static inline VkPhysicalDevice unwrap_phys_dev(const VkPhysicalDevice physical_device,  wrapped_phys_dev_obj **phys_dev) {
+   *phys_dev = reinterpret_cast<wrapped_phys_dev_obj *> (physical_device);
+   return reinterpret_cast <VkPhysicalDevice> ((*phys_dev)->obj);
+}
+
+static void create_device_register_extensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
+    VkLayerDispatchTable *pDisp = device_dispatch_table(device);
+    PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
+    pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
+    pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
+    pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
+    pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
+    pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
+}
diff --git a/tests/loader_validation_tests.cpp b/tests/loader_validation_tests.cpp
index 57a2e9f..a6431ff 100644
--- a/tests/loader_validation_tests.cpp
+++ b/tests/loader_validation_tests.cpp
@@ -25,11 +25,299 @@
  * Author: Jeremy Hayes <jeremy@lunarG.com>
  */
 
+#include <algorithm>
+#include <iostream>
 #include <memory>
+#include <string>
+#include <vector>
 
 #include <vulkan/vulkan.h>
 #include "test_common.h"
 
+namespace VK
+{
+
+struct InstanceCreateInfo
+{
+    InstanceCreateInfo() :
+        info // MSVC can't handle list initialization, thus explicit construction herein.
+        (
+            VkInstanceCreateInfo
+            {
+                VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
+                nullptr, // pNext
+                0, // flags
+                nullptr, // pApplicationInfo
+                0, // enabledLayerCount
+                nullptr, // ppEnabledLayerNames
+                0, //enabledExtensionCount
+                nullptr // ppEnabledExtensionNames
+            }
+        )
+    {
+    }
+
+    InstanceCreateInfo& sType(VkStructureType const& sType)
+    {
+        info.sType = sType;
+
+        return *this;
+    }
+
+    InstanceCreateInfo& pNext(void const*const pNext)
+    {
+        info.pNext = pNext;
+
+        return *this;
+    }
+
+    InstanceCreateInfo& flags(VkInstanceCreateFlags const& flags)
+    {
+        info.flags = flags;
+
+        return *this;
+    }
+
+    InstanceCreateInfo& pApplicationInfo(VkApplicationInfo const*const pApplicationInfo)
+    {
+        info.pApplicationInfo = pApplicationInfo;
+
+        return *this;
+    }
+
+    InstanceCreateInfo& enabledLayerCount(uint32_t const& enabledLayerCount)
+    {
+        info.enabledLayerCount = enabledLayerCount;
+
+        return *this;
+    }
+
+    InstanceCreateInfo& ppEnabledLayerNames(char const*const*const ppEnabledLayerNames)
+    {
+        info.ppEnabledLayerNames = ppEnabledLayerNames;
+
+        return *this;
+    }
+
+    InstanceCreateInfo& enabledExtensionCount(uint32_t const& enabledExtensionCount)
+    {
+        info.enabledExtensionCount = enabledExtensionCount;
+
+        return *this;
+    }
+
+    InstanceCreateInfo& ppEnabledExtensionNames(char const*const*const ppEnabledExtensionNames)
+    {
+        info.ppEnabledExtensionNames = ppEnabledExtensionNames;
+
+        return *this;
+    }
+
+    operator VkInstanceCreateInfo const*() const
+    {
+        return &info;
+    }
+
+    operator VkInstanceCreateInfo*()
+    {
+        return &info;
+    }
+
+    VkInstanceCreateInfo info;
+};
+
+struct DeviceQueueCreateInfo
+{
+    DeviceQueueCreateInfo() :
+        info // MSVC can't handle list initialization, thus explicit construction herein.
+        (
+            VkDeviceQueueCreateInfo
+            {
+                VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
+                nullptr, // pNext
+                0, // flags
+                0, // queueFamilyIndex
+                0, // queueCount
+                nullptr // pQueuePriorities
+            }
+        )
+    {
+    }
+
+    DeviceQueueCreateInfo& sType(VkStructureType const& sType)
+    {
+        info.sType = sType;
+
+        return *this;
+    }
+
+    DeviceQueueCreateInfo& pNext(void const*const pNext)
+    {
+        info.pNext = pNext;
+
+        return *this;
+    }
+
+    DeviceQueueCreateInfo& flags(VkDeviceQueueCreateFlags const& flags)
+    {
+        info.flags = flags;
+
+        return *this;
+    }
+
+    DeviceQueueCreateInfo& queueFamilyIndex(uint32_t const& queueFamilyIndex)
+    {
+        info.queueFamilyIndex = queueFamilyIndex;
+
+        return *this;
+    }
+
+    DeviceQueueCreateInfo& queueCount(uint32_t const& queueCount)
+    {
+        info.queueCount = queueCount;
+
+        return *this;
+    }
+
+    DeviceQueueCreateInfo& pQueuePriorities(float const*const pQueuePriorities)
+    {
+        info.pQueuePriorities = pQueuePriorities;
+
+        return *this;
+    }
+
+    operator VkDeviceQueueCreateInfo()
+    {
+        return info;
+    }
+
+    VkDeviceQueueCreateInfo info;
+};
+
+struct DeviceCreateInfo
+{
+    DeviceCreateInfo() :
+        info // MSVC can't handle list initialization, thus explicit construction herein.
+        (
+            VkDeviceCreateInfo
+            {
+                VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
+                nullptr, // pNext
+                0, // flags
+                0, // queueCreateInfoCount
+                nullptr, // pQueueCreateInfos
+                0, // enabledLayerCount
+                nullptr, // ppEnabledLayerNames
+                0, // enabledExtensionCount
+                nullptr, // ppEnabledExtensionNames
+                nullptr // pEnabledFeatures
+            }
+        )
+    {
+    }
+
+    DeviceCreateInfo& sType(VkStructureType const& sType)
+    {
+        info.sType = sType;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& pNext(void const*const pNext)
+    {
+        info.pNext = pNext;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& flags(VkDeviceQueueCreateFlags const& flags)
+    {
+        info.flags = flags;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& queueCreateInfoCount(uint32_t const& queueCreateInfoCount)
+    {
+        info.queueCreateInfoCount = queueCreateInfoCount;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& pQueueCreateInfos(VkDeviceQueueCreateInfo const*const pQueueCreateInfos)
+    {
+        info.pQueueCreateInfos = pQueueCreateInfos;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& enabledLayerCount(uint32_t const& enabledLayerCount)
+    {
+        info.enabledLayerCount = enabledLayerCount;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& ppEnabledLayerNames(char const*const*const ppEnabledLayerNames)
+    {
+        info.ppEnabledLayerNames = ppEnabledLayerNames;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& enabledExtensionCount(uint32_t const& enabledExtensionCount)
+    {
+        info.enabledExtensionCount = enabledExtensionCount;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& ppEnabledExtensionNames(char const*const*const ppEnabledExtensionNames)
+    {
+        info.ppEnabledExtensionNames = ppEnabledExtensionNames;
+
+        return *this;
+    }
+
+    DeviceCreateInfo& pEnabledFeatures(VkPhysicalDeviceFeatures const*const pEnabledFeatures)
+    {
+        info.pEnabledFeatures = pEnabledFeatures;
+
+        return *this;
+    }
+
+    operator VkDeviceCreateInfo const*() const
+    {
+        return &info;
+    }
+
+    operator VkDeviceCreateInfo*()
+    {
+        return &info;
+    }
+
+    VkDeviceCreateInfo info;
+};
+
+}
+
+struct CommandLine : public ::testing::Test
+{
+    static void Initialize(int argc, char **argv)
+    {
+        arguments.assign(argv, argv + argc);
+    };
+
+    static void SetUpTestCase() {};
+    static void TearDownTestCase() {};
+
+    static std::vector<std::string> arguments;
+};
+std::vector<std::string> CommandLine::arguments;
+
+struct EnumerateInstanceLayerProperties : public CommandLine {};
+struct EnumerateInstanceExtensionProperties : public CommandLine {};
+
 // Test groups:
 // LX = lunar exchange
 // LVLGH = loader and validation github
@@ -37,7 +325,7 @@
 
 TEST(LX435, InstanceCreateInfoConst)
 {
-    const VkInstanceCreateInfo info =
+    VkInstanceCreateInfo const info =
     {
         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
         nullptr,
@@ -52,6 +340,8 @@
     VkInstance instance = VK_NULL_HANDLE;
     VkResult result = vkCreateInstance(&info, VK_NULL_HANDLE, &instance);
     EXPECT_EQ(result, VK_SUCCESS);
+
+    vkDestroyInstance(instance, nullptr);
 }
 
 TEST(LX475, DestroyInstanceNullHandle)
@@ -64,12 +354,535 @@
     vkDestroyDevice(VK_NULL_HANDLE, nullptr);
 }
 
+TEST(CreateInstance, ExtensionNotPresent)
+{
+    char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
+    auto const info = VK::InstanceCreateInfo().
+        enabledExtensionCount(1).
+        ppEnabledExtensionNames(names);
+
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
+
+    // It's not necessary to destroy the instance because it will not be created successfully.
+}
+
+TEST(CreateInstance, LayerNotPresent)
+{
+    char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
+    auto const info = VK::InstanceCreateInfo().
+        enabledLayerCount(1).
+        ppEnabledLayerNames(names);
+
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_ERROR_LAYER_NOT_PRESENT);
+
+    // It's not necessary to destroy the instance because it will not be created successfully.
+}
+
+// Used by run_loader_tests.sh to test for layer insertion.
+TEST(CreateInstance, LayerPresent)
+{
+    char const*const names[] = {"VK_LAYER_LUNARG_parameter_validation"}; // Temporary required due to MSVC bug.
+    auto const info = VK::InstanceCreateInfo().
+        enabledLayerCount(1).
+        ppEnabledLayerNames(names);
+
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    vkDestroyInstance(instance, nullptr);
+}
+
+TEST(CreateDevice, ExtensionNotPresent)
+{
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    uint32_t physicalCount = 0;
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    for(uint32_t p = 0; p < physicalCount; ++p)
+    {
+        uint32_t familyCount = 0;
+        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
+        ASSERT_EQ(result, VK_SUCCESS);
+        ASSERT_GT(familyCount, 0u);
+
+        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
+        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
+        ASSERT_EQ(result, VK_SUCCESS);
+        ASSERT_GT(familyCount, 0u);
+
+        for(uint32_t q = 0; q < familyCount; ++q)
+        {
+            if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
+            {
+                continue;
+            }
+
+            float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
+            VkDeviceQueueCreateInfo const queueInfo[1]
+            {
+                VK::DeviceQueueCreateInfo().
+                    queueFamilyIndex(q).
+                    queueCount(1).
+                    pQueuePriorities(priorities)
+            };
+
+            char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
+            auto const deviceInfo = VK::DeviceCreateInfo().
+                queueCreateInfoCount(1).
+                pQueueCreateInfos(queueInfo).
+                enabledExtensionCount(1).
+                ppEnabledExtensionNames(names);
+
+            VkDevice device;
+            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
+            ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
+
+            // It's not necessary to destroy the device because it will not be created successfully.
+        }
+    }
+
+    vkDestroyInstance(instance, nullptr);
+}
+
+// LX535 / MI-76: Device layers are deprecated.
+// For backwards compatibility, they are allowed, but must be ignored.
+// Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice.
+TEST(CreateDevice, LayersNotPresent)
+{
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    uint32_t physicalCount = 0;
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    for(uint32_t p = 0; p < physicalCount; ++p)
+    {
+        uint32_t familyCount = 0;
+        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
+        ASSERT_EQ(result, VK_SUCCESS);
+        ASSERT_GT(familyCount, 0u);
+
+        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
+        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
+        ASSERT_EQ(result, VK_SUCCESS);
+        ASSERT_GT(familyCount, 0u);
+
+        for(uint32_t q = 0; q < familyCount; ++q)
+        {
+            if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
+            {
+                continue;
+            }
+
+            float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
+            VkDeviceQueueCreateInfo const queueInfo[1]
+            {
+                VK::DeviceQueueCreateInfo().
+                    queueFamilyIndex(q).
+                    queueCount(1).
+                    pQueuePriorities(priorities)
+            };
+
+            char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
+            auto const deviceInfo = VK::DeviceCreateInfo().
+                queueCreateInfoCount(1).
+                pQueueCreateInfos(queueInfo).
+                enabledLayerCount(1).
+                ppEnabledLayerNames(names);
+
+            VkDevice device;
+            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
+            ASSERT_EQ(result, VK_SUCCESS);
+
+            vkDestroyDevice(device, nullptr);
+        }
+    }
+
+    vkDestroyInstance(instance, nullptr);
+}
+
+TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable)
+{
+    uint32_t count = 0u;
+    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    // We need atleast two for the test to be relevant.
+    if(count < 2u)
+    {
+        return;
+    }
+
+    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
+    count = 1;
+    result = vkEnumerateInstanceLayerProperties(&count, properties.get());
+    ASSERT_EQ(result, VK_INCOMPLETE);
+}
+
+TEST(EnumerateDeviceLayerProperties, PropertyCountLessThanAvailable)
+{
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    uint32_t physicalCount = 0;
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    for(uint32_t p = 0; p < physicalCount; ++p)
+    {
+        uint32_t count = 0u;
+        result = vkEnumerateDeviceLayerProperties(physical[p], &count, nullptr);
+        ASSERT_EQ(result, VK_SUCCESS);
+
+        // We need atleast two for the test to be relevant.
+        if(count < 2u)
+        {
+            continue;
+        }
+
+        std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
+        count = 1;
+        result = vkEnumerateDeviceLayerProperties(physical[p], &count, properties.get());
+        ASSERT_EQ(result, VK_INCOMPLETE);
+    }
+
+    vkDestroyInstance(instance, nullptr);
+}
+
+TEST_F(EnumerateInstanceLayerProperties, Count)
+{
+    uint32_t count = 0u;
+    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    if(std::find(arguments.begin(), arguments.end(), "count") != arguments.end())
+    {
+        std::cout << "count=" << count << '\n';
+    }
+}
+
+TEST_F(EnumerateInstanceLayerProperties, OnePass)
+{
+    // Count required for this test.
+    if(std::find(arguments.begin(), arguments.end(), "count") == arguments.end())
+    {
+        return;
+    }
+
+    uint32_t count = std::stoul(arguments[2]);
+
+    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
+    VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
+    {
+        for(uint32_t p = 0; p < count; ++p)
+        {
+            std::cout << "properties[" << p << "] ="
+                << ' ' << properties[p].layerName
+                << ' ' << properties[p].specVersion
+                << ' ' << properties[p].implementationVersion
+                << ' ' << properties[p].description << '\n';
+        }
+    }
+}
+
+TEST_F(EnumerateInstanceLayerProperties, TwoPass)
+{
+    uint32_t count = 0u;
+    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
+    result = vkEnumerateInstanceLayerProperties(&count, properties.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
+    {
+        for(uint32_t p = 0; p < count; ++p)
+        {
+            std::cout << "properties[" << p << "] ="
+                << ' ' << properties[p].layerName
+                << ' ' << properties[p].specVersion
+                << ' ' << properties[p].implementationVersion
+                << ' ' << properties[p].description << '\n';
+        }
+    }
+}
+
+TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable)
+{
+    uint32_t count = 0u;
+    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    // We need atleast two for the test to be relevant.
+    if(count < 2u)
+    {
+        return;
+    }
+
+    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
+    count = 1;
+    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
+    ASSERT_EQ(result, VK_INCOMPLETE);
+}
+
+TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable)
+{
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    uint32_t physicalCount = 0;
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    for(uint32_t p = 0; p < physicalCount; ++p)
+    {
+        uint32_t count = 0u;
+        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
+        ASSERT_EQ(result, VK_SUCCESS);
+
+        // We need atleast two for the test to be relevant.
+        if(count < 2u)
+        {
+            continue;
+        }
+
+        std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
+        count = 1;
+        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
+        ASSERT_EQ(result, VK_INCOMPLETE);
+    }
+
+    vkDestroyInstance(instance, nullptr);
+}
+
+TEST_F(EnumerateInstanceExtensionProperties, Count)
+{
+    uint32_t count = 0u;
+    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    if(std::find(arguments.begin(), arguments.end(), "count") != arguments.end())
+    {
+        std::cout << "count=" << count << '\n';
+    }
+}
+
+TEST_F(EnumerateInstanceExtensionProperties, OnePass)
+{
+    // Count required for this test.
+    if(std::find(arguments.begin(), arguments.end(), "count") == arguments.end())
+    {
+        return;
+    }
+
+    uint32_t count = std::stoul(arguments[2]);
+
+    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
+    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
+    {
+        for(uint32_t p = 0; p < count; ++p)
+        {
+            std::cout << "properties[" << p << "] ="
+                << ' ' << properties[p].extensionName
+                << ' ' << properties[p].specVersion << '\n';
+        }
+    }
+}
+
+TEST_F(EnumerateInstanceExtensionProperties, TwoPass)
+{
+    uint32_t count = 0u;
+    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
+    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
+    {
+        for(uint32_t p = 0; p < count; ++p)
+        {
+            std::cout << "properties[" << p << "] ="
+                << ' ' << properties[p].extensionName
+                << ' ' << properties[p].specVersion << '\n';
+        }
+    }
+}
+
+TEST_F(EnumerateInstanceExtensionProperties, InstanceExtensionEnumerated)
+{
+    uint32_t count = 0u;
+    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
+    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    ASSERT_NE(std::find_if(
+        &properties[0],
+        &properties[count],
+        [](VkExtensionProperties const& properties)
+        {
+            return strcmp(properties.extensionName, "VK_KHR_surface") == 0;
+        }),
+        &properties[count]);
+}
+
+TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated)
+{
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    uint32_t physicalCount = 0;
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    for(uint32_t p = 0; p < physicalCount; ++p)
+    {
+        uint32_t count = 0u;
+        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
+        ASSERT_EQ(result, VK_SUCCESS);
+
+        std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
+        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
+        ASSERT_EQ(result, VK_SUCCESS);
+
+        ASSERT_NE(std::find_if(
+            &properties[0],
+            &properties[count],
+            [](VkExtensionProperties const& properties)
+            {
+                return strcmp(properties.extensionName, "VK_KHR_swapchain") == 0;
+            }),
+            &properties[count]);
+    }
+
+    vkDestroyInstance(instance, nullptr);
+}
+
+TEST(WrapObjects, Insert)
+{
+    VkInstance instance = VK_NULL_HANDLE;
+    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
+    ASSERT_EQ(result, VK_SUCCESS);
+
+    uint32_t physicalCount = 0;
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
+    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
+    ASSERT_EQ(result, VK_SUCCESS);
+    ASSERT_GT(physicalCount, 0u);
+
+    for(uint32_t p = 0; p < physicalCount; ++p)
+    {
+        uint32_t familyCount = 0;
+        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
+        ASSERT_EQ(result, VK_SUCCESS);
+        ASSERT_GT(familyCount, 0u);
+
+        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
+        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
+        ASSERT_EQ(result, VK_SUCCESS);
+        ASSERT_GT(familyCount, 0u);
+
+        for(uint32_t q = 0; q < familyCount; ++q)
+        {
+            if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
+            {
+                continue;
+            }
+
+            float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
+            VkDeviceQueueCreateInfo const queueInfo[1]
+            {
+                VK::DeviceQueueCreateInfo().
+                    queueFamilyIndex(q).
+                    queueCount(1).
+                    pQueuePriorities(priorities)
+            };
+
+            auto const deviceInfo = VK::DeviceCreateInfo().
+                queueCreateInfoCount(1).
+                pQueueCreateInfos(queueInfo);
+
+            VkDevice device;
+            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
+            ASSERT_EQ(result, VK_SUCCESS);
+
+            vkDestroyDevice(device, nullptr);
+        }
+    }
+
+    vkDestroyInstance(instance, nullptr);
+}
+
 int main(int argc, char **argv)
 {
     int result;
 
     ::testing::InitGoogleTest(&argc, argv);
 
+    if(argc > 0)
+    {
+        CommandLine::Initialize(argc, argv);
+    }
+
     result = RUN_ALL_TESTS();
 
     return result;
diff --git a/tests/run_all_tests.sh b/tests/run_all_tests.sh
index 1b93287..8cf691e 100755
--- a/tests/run_all_tests.sh
+++ b/tests/run_all_tests.sh
@@ -7,7 +7,7 @@
 set -e
 
 #Verify that the loader is working
-./vk_loader_validation_tests
+./run_loader_tests.sh
 
 # Verify that validation checks in source match documentation
 ./vkvalidatelayerdoc.sh
@@ -16,4 +16,3 @@
 # catch the errors that they are supposed to by intentionally doing things
 # that are wrong
 ./vk_layer_validation_tests
-
diff --git a/tests/run_loader_tests.sh b/tests/run_loader_tests.sh
new file mode 100755
index 0000000..c640bbe
--- /dev/null
+++ b/tests/run_loader_tests.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+pushd $(dirname "$0") > /dev/null
+
+RunCreateInstanceTest()
+{
+    # Check for layer insertion via CreateInstance.
+    output=$(VK_LOADER_DEBUG=all \
+       GTEST_FILTER=CreateInstance.LayerPresent \
+       ./vk_loader_validation_tests 2>&1)
+
+    echo "$output" | grep -q "Insert instance layer VK_LAYER_LUNARG_parameter_validation"
+    ec=$?
+
+    if [ $ec -eq 1 ]
+    then
+       echo "CreateInstance insertion test FAILED - parameter-validation not detected in instance layers" >&2
+       exit 1
+    fi
+    echo "CreateInstance Insertion test PASSED"
+}
+
+RunEnumerateInstanceLayerPropertiesTest()
+{
+    count=$(GTEST_FILTER=EnumerateInstanceLayerProperties.Count \
+        ./vk_loader_validation_tests count 2>&1 |
+        grep -o 'count=[0-9]\+' | sed 's/^.*=//')
+
+    if [ "$count" -gt 1 ]
+    then
+        diff \
+            <(GTEST_PRINT_TIME=0 \
+                GTEST_FILTER=EnumerateInstanceLayerProperties.OnePass \
+                ./vk_loader_validation_tests count "$count" properties 2>&1 |
+                grep 'properties') \
+            <(GTEST_PRINT_TIME=0 \
+                GTEST_FILTER=EnumerateInstanceLayerProperties.TwoPass \
+                ./vk_loader_validation_tests properties 2>&1 |
+                grep 'properties')
+    fi
+    ec=$?
+
+    if [ $ec -eq 1 ]
+    then
+        echo "EnumerateInstanceLayerProperties OnePass vs TwoPass test FAILED - properties do not match" >&2
+        exit 1
+    fi
+    echo "EnumerateInstanceLayerProperties OnePass vs TwoPass test PASSED"
+}
+
+RunEnumerateInstanceExtensionPropertiesTest()
+{
+    count=$(GTEST_FILTER=EnumerateInstanceExtensionProperties.Count \
+        ./vk_loader_validation_tests count 2>&1 |
+        grep -o 'count=[0-9]\+' | sed 's/^.*=//')
+
+    if [ "$count" -gt 1 ]
+    then
+        diff \
+            <(GTEST_PRINT_TIME=0 \
+                GTEST_FILTER=EnumerateInstanceExtensionProperties.OnePass \
+                ./vk_loader_validation_tests count "$count" properties 2>&1 |
+                grep 'properties') \
+            <(GTEST_PRINT_TIME=0 \
+                GTEST_FILTER=EnumerateInstanceExtensionProperties.TwoPass \
+                ./vk_loader_validation_tests properties 2>&1 |
+                grep 'properties')
+    fi
+    ec=$?
+
+    if [ $ec -eq 1 ]
+    then
+        echo "EnumerateInstanceExtensionProperties OnePass vs TwoPass test FAILED - properties do not match" >&2
+        exit 1
+    fi
+    echo "EnumerateInstanceExtensionProperties OnePass vs TwoPass test PASSED"
+}
+
+./vk_loader_validation_tests
+
+RunCreateInstanceTest
+RunEnumerateInstanceLayerPropertiesTest
+RunEnumerateInstanceExtensionPropertiesTest
+
+# Test the wrap objects layer.
+./run_wrap_objects_tests.sh
+
+popd > /dev/null
diff --git a/tests/run_wrap_objects_tests.sh b/tests/run_wrap_objects_tests.sh
new file mode 100755
index 0000000..152cd32
--- /dev/null
+++ b/tests/run_wrap_objects_tests.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+
+pushd $(dirname "$0") > /dev/null
+
+# Check for insertion of wrap-objects layer.
+output=$(VK_LAYER_PATH=$VK_LAYER_PATH:`pwd`/layers \
+   LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/layers \
+   VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_wrap_objects \
+   VK_LOADER_DEBUG=all \
+   GTEST_FILTER=WrapObjects.Insert \
+   ./vk_loader_validation_tests 2>&1)
+
+echo "$output" | grep -q "Insert instance layer VK_LAYER_LUNARG_wrap_objects"
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Insertion test FAILED - wrap-objects not detected in instance layers" >&2
+   exit 1
+fi
+
+echo "$output" | grep -q "Insert device layer VK_LAYER_LUNARG_wrap_objects"
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Insertion test FAILED - wrap-objects not detected in device layers" >&2
+   exit 1
+fi
+echo "Insertion test PASSED"
+
+# Check for insertion of wrap-objects layer in front.
+output=$(VK_LAYER_PATH=$VK_LAYER_PATH:`pwd`/layers \
+   LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/layers \
+   VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_parameter_validation:VK_LAYER_LUNARG_wrap_objects \
+   VK_LOADER_DEBUG=all \
+   GTEST_FILTER=WrapObjects.Insert \
+   ./vk_loader_validation_tests 2>&1)
+
+echo "$output" | grep -q "Insert instance layer VK_LAYER_LUNARG_wrap_objects"
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Front insertion test FAILED - wrap-objects not detected in instance layers" >&2
+   exit 1
+fi
+
+echo "$output" | grep -q "Insert device layer VK_LAYER_LUNARG_wrap_objects"
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Front insertion test FAILED - wrap-objects not detected in device layers" >&2
+   exit 1
+fi
+echo "Front insertion test PASSED"
+
+# Check for insertion of wrap-objects layer in back.
+output=$(VK_LAYER_PATH=$VK_LAYER_PATH:`pwd`/layers \
+   LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/layers \
+   VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_wrap_objects:VK_LAYER_LUNARG_parameter_validation \
+   VK_LOADER_DEBUG=all \
+   GTEST_FILTER=WrapObjects.Insert \
+   ./vk_loader_validation_tests 2>&1)
+
+echo "$output" | grep -q "Insert instance layer VK_LAYER_LUNARG_wrap_objects"
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Back insertion test FAILED - wrap-objects not detected in instance layers" >&2
+   exit 1
+fi
+
+echo "$output" | grep -q "Insert device layer VK_LAYER_LUNARG_wrap_objects"
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Back insertion test FAILED - wrap-objects not detected in device layers" >&2
+   exit 1
+fi
+echo "Back insertion test PASSED"
+
+# Check for insertion of wrap-objects layer in middle.
+output=$(VK_LAYER_PATH=$VK_LAYER_PATH:`pwd`/layers \
+   LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/layers \
+   VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_image:VK_LAYER_LUNARG_wrap_objects:VK_LAYER_LUNARG_parameter_validation \
+   VK_LOADER_DEBUG=all \
+   GTEST_FILTER=WrapObjects.Insert \
+   ./vk_loader_validation_tests 2>&1)
+
+echo "$output" | grep -q "Insert instance layer VK_LAYER_LUNARG_wrap_objects"
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Middle insertion test FAILED - wrap-objects not detected in instance layers" >&2
+   exit 1
+fi
+
+echo "$output" | grep -q "Insert device layer VK_LAYER_LUNARG_wrap_objects"
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Middle insertion test FAILED - wrap-objects not detected in device layers" >&2
+   exit 1
+fi
+echo "Middle insertion test PASSED"
+
+# Run the layer validation tests with and without the wrap-objects layer. Diff the results.
+diff \
+   <(GTEST_PRINT_TIME=0 \
+      ./vk_layer_validation_tests) \
+   <(GTEST_PRINT_TIME=0 \
+      VK_LAYER_PATH=$VK_LAYER_PATH:`pwd`/layers \
+      LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/layers \
+      VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_wrap_objects \
+      ./vk_layer_validation_tests)
+ec=$?
+
+if [ $ec -eq 1 ]
+then
+   echo "Wrap-objects layer validation tests FAILED - wrap-objects altered the results of the layer validation tests" >&2
+   exit 1
+fi
+echo "Wrap-objects layer validation tests PASSED"
+
+popd > /dev/null
+
+exit 0
diff --git a/tests/test_environment.cpp b/tests/test_environment.cpp
index 246a175..9427b67 100644
--- a/tests/test_environment.cpp
+++ b/tests/test_environment.cpp
@@ -85,7 +85,6 @@
 
     std::vector<const char *> instance_extension_names;
     std::vector<const char *> device_extension_names;
-    std::vector<const char *> device_layer_names;
 
     instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
     device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
@@ -150,7 +149,7 @@
     for (uint32_t i = 0; i < count; i++) {
         devs_.push_back(new Device(gpus[i]));
         if (i == default_dev_) {
-            devs_[i]->init(device_layer_names, device_extension_names);
+            devs_[i]->init(device_extension_names);
             ASSERT_NE(true, devs_[i]->graphics_queues().empty());
         }
     }
diff --git a/tests/vk_layer_settings.txt b/tests/vk_layer_settings.txt
index 88ebae0..cfa3122 100644
--- a/tests/vk_layer_settings.txt
+++ b/tests/vk_layer_settings.txt
@@ -6,8 +6,6 @@
 lunarg_parameter_validation.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG
 google_threading.report_flags = error
 google_threading.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG
-lunarg_device_limits.report_flags = error
-lunarg_device_limits.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG
 lunarg_swapchain.report_flags = error
 lunarg_swapchain.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG
 lunarg_image.report_flags = error
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index 64d428b..0039423 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -30,6 +30,45 @@
         assert(fp##entrypoint != NULL);                                        \
     }
 
+// TODO : These functions are duplicated is vk_layer_utils.cpp, share code
+// Return true if format contains depth and stencil information
+bool vk_format_is_depth_and_stencil(VkFormat format) {
+    bool is_ds = false;
+
+    switch (format) {
+    case VK_FORMAT_D16_UNORM_S8_UINT:
+    case VK_FORMAT_D24_UNORM_S8_UINT:
+    case VK_FORMAT_D32_SFLOAT_S8_UINT:
+        is_ds = true;
+        break;
+    default:
+        break;
+    }
+    return is_ds;
+}
+
+// Return true if format is a stencil-only format
+bool vk_format_is_stencil_only(VkFormat format) {
+    return (format == VK_FORMAT_S8_UINT);
+}
+
+// Return true if format is a depth-only format
+bool vk_format_is_depth_only(VkFormat format) {
+    bool is_depth = false;
+
+    switch (format) {
+    case VK_FORMAT_D16_UNORM:
+    case VK_FORMAT_X8_D24_UNORM_PACK32:
+    case VK_FORMAT_D32_SFLOAT:
+        is_depth = true;
+        break;
+    default:
+        break;
+    }
+
+    return is_depth;
+}
+
 VkRenderFramework::VkRenderFramework()
     : inst(VK_NULL_HANDLE), m_device(NULL), m_commandPool(VK_NULL_HANDLE),
       m_commandBuffer(NULL), m_renderPass(VK_NULL_HANDLE),
@@ -56,7 +95,6 @@
 
 void VkRenderFramework::InitFramework() {
     std::vector<const char *> instance_layer_names;
-    std::vector<const char *> device_layer_names;
     std::vector<const char *> instance_extension_names;
     std::vector<const char *> device_extension_names;
     instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
@@ -68,13 +106,12 @@
 #ifdef VK_USE_PLATFORM_XCB_KHR
     instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
 #endif
-    InitFramework(instance_layer_names, device_layer_names,
-                  instance_extension_names, device_extension_names);
+    InitFramework(instance_layer_names, instance_extension_names,
+                  device_extension_names);
 }
 
 void VkRenderFramework::InitFramework(
     std::vector<const char *> instance_layer_names,
-    std::vector<const char *> device_layer_names,
     std::vector<const char *> instance_extension_names,
     std::vector<const char *> device_extension_names,
     PFN_vkDebugReportCallbackEXT dbgFunction, void *userData) {
@@ -139,8 +176,7 @@
     }
 
     /* TODO: Verify requested physical device extensions are available */
-    m_device =
-        new VkDeviceObj(0, objs[0], device_layer_names, device_extension_names);
+    m_device = new VkDeviceObj(0, objs[0], device_extension_names);
 
     /* Now register callback on device */
     if (0) {
@@ -401,10 +437,9 @@
 }
 
 VkDeviceObj::VkDeviceObj(uint32_t id, VkPhysicalDevice obj,
-                         std::vector<const char *> &layer_names,
                          std::vector<const char *> &extension_names)
     : vk_testing::Device(obj), id(id) {
-    init(layer_names, extension_names);
+    init(extension_names);
 
     props = phy().properties();
     queue_props = phy().queue_properties();
@@ -591,7 +626,7 @@
 }
 
 void VkImageObj::SetLayout(VkCommandBufferObj *cmd_buf,
-                           VkImageAspectFlagBits aspect,
+                           VkImageAspectFlags aspect,
                            VkImageLayout image_layout) {
     VkFlags src_mask, dst_mask;
     const VkFlags all_cache_outputs =
@@ -661,11 +696,14 @@
         break;
     }
 
+    if (m_descriptorImageInfo.imageLayout == VK_IMAGE_LAYOUT_UNDEFINED)
+        src_mask = 0;
+
     ImageMemoryBarrier(cmd_buf, aspect, src_mask, dst_mask, image_layout);
     m_descriptorImageInfo.imageLayout = image_layout;
 }
 
-void VkImageObj::SetLayout(VkImageAspectFlagBits aspect,
+void VkImageObj::SetLayout(VkImageAspectFlags aspect,
                            VkImageLayout image_layout) {
     VkResult U_ASSERT_ONLY err;
 
@@ -701,9 +739,10 @@
     return true;
 }
 
-void VkImageObj::init(uint32_t w, uint32_t h, VkFormat fmt, VkFlags usage,
+void VkImageObj::init_no_layout(uint32_t w, uint32_t h, VkFormat fmt, VkFlags usage,
                       VkImageTiling requested_tiling,
                       VkMemoryPropertyFlags reqs) {
+
     VkFormatProperties image_fmt;
     VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
 
@@ -741,6 +780,13 @@
     imageCreateInfo.usage = usage;
 
     vk_testing::Image::init(*m_device, imageCreateInfo, reqs);
+}
+
+void VkImageObj::init(uint32_t w, uint32_t h, VkFormat fmt, VkFlags usage,
+                      VkImageTiling requested_tiling,
+                      VkMemoryPropertyFlags reqs) {
+
+    init_no_layout(w, h, fmt, usage, requested_tiling, reqs);
 
     VkImageLayout newLayout;
     if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
@@ -750,7 +796,17 @@
     else
         newLayout = m_descriptorImageInfo.imageLayout;
 
-    SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, newLayout);
+    VkImageAspectFlags image_aspect = 0;
+    if (vk_format_is_depth_and_stencil(fmt)) {
+        image_aspect = VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
+    } else if (vk_format_is_depth_only(fmt)) {
+        image_aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
+    } else if (vk_format_is_stencil_only(fmt)) {
+        image_aspect = VK_IMAGE_ASPECT_STENCIL_BIT;
+    } else { // color
+        image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
+    }
+    SetLayout(image_aspect, newLayout);
 }
 
 VkResult VkImageObj::CopyImage(VkImageObj &src_image) {
@@ -900,11 +956,18 @@
  * Basic ConstantBuffer constructor. Then use create methods to fill in the
  * details.
  */
-VkConstantBufferObj::VkConstantBufferObj(VkDeviceObj *device) {
+VkConstantBufferObj::VkConstantBufferObj(VkDeviceObj *device,
+                                         VkBufferUsageFlags usage) {
     m_device = device;
     m_commandBuffer = 0;
 
     memset(&m_descriptorBufferInfo, 0, sizeof(m_descriptorBufferInfo));
+
+    // Special case for usages outside of original limits of framework
+    if ((VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) !=
+            usage) {
+        init_no_mem(*m_device, create_info(0, usage));
+    }
 }
 
 VkConstantBufferObj::~VkConstantBufferObj() {
@@ -917,7 +980,8 @@
 }
 
 VkConstantBufferObj::VkConstantBufferObj(VkDeviceObj *device, int constantCount,
-                                         int constantSize, const void *data) {
+                                         int constantSize, const void *data,
+                                         VkBufferUsageFlags usage) {
     m_device = device;
     m_commandBuffer = 0;
 
@@ -926,12 +990,19 @@
     m_stride = constantSize;
 
     VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
-                                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
-    const size_t allocationSize = constantCount * constantSize;
-    init_as_src_and_dst(*m_device, allocationSize, reqs);
+            VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+    const VkDeviceSize allocationSize =
+            static_cast<VkDeviceSize>(constantCount * constantSize);
+
+    if ((VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) ==
+            usage) {
+        init_as_src_and_dst(*m_device, allocationSize, reqs);
+    } else {
+        init(*m_device, create_info(allocationSize, usage), reqs);
+    }
 
     void *pData = memory().map();
-    memcpy(pData, data, allocationSize);
+    memcpy(pData, data, static_cast<size_t>(allocationSize));
     memory().unmap();
 
     /*
@@ -1218,13 +1289,13 @@
 }
 
 void VkPipelineObj::AddVertexInputAttribs(
-    VkVertexInputAttributeDescription *vi_attrib, int count) {
+    VkVertexInputAttributeDescription *vi_attrib, uint32_t count) {
     m_vi_state.pVertexAttributeDescriptions = vi_attrib;
     m_vi_state.vertexAttributeDescriptionCount = count;
 }
 
-void VkPipelineObj::AddVertexInputBindings(
-    VkVertexInputBindingDescription *vi_binding, int count) {
+void VkPipelineObj::AddVertexInputBindings(VkVertexInputBindingDescription *vi_binding,
+                                           uint32_t count) {
     m_vi_state.pVertexBindingDescriptions = vi_binding;
     m_vi_state.vertexBindingDescriptionCount = count;
 }
@@ -1313,6 +1384,9 @@
     m_vi_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
     info.pVertexInputState = &m_vi_state;
 
+    m_ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+    info.pInputAssemblyState = &m_ia_state;
+
     info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
     info.pNext = NULL;
     info.flags = 0;
@@ -1344,7 +1418,6 @@
 
     info.renderPass = render_pass;
     info.subpass = 0;
-    info.pInputAssemblyState = &m_ia_state;
     info.pViewportState = &m_vp_state;
     info.pRasterizationState = &m_rs_state;
     info.pMultisampleState = &m_ms_state;
@@ -1484,7 +1557,7 @@
 
 void VkCommandBufferObj::UpdateBuffer(VkBuffer buffer, VkDeviceSize dstOffset,
                                       VkDeviceSize dataSize,
-                                      const uint32_t *pData) {
+                                      const void *pData) {
     vkCmdUpdateBuffer(handle(), buffer, dstOffset, dataSize, pData);
 }
 
@@ -1619,12 +1692,12 @@
     vkCmdDraw(handle(), vertexCount, instanceCount, firstVertex, firstInstance);
 }
 
-void VkCommandBufferObj::QueueCommandBuffer() {
+void VkCommandBufferObj::QueueCommandBuffer(bool checkSuccess) {
     VkFence nullFence = {VK_NULL_HANDLE};
-    QueueCommandBuffer(nullFence);
+    QueueCommandBuffer(nullFence, checkSuccess);
 }
 
-void VkCommandBufferObj::QueueCommandBuffer(VkFence fence) {
+void VkCommandBufferObj::QueueCommandBuffer(VkFence fence, bool checkSuccess) {
     VkResult err = VK_SUCCESS;
 
     // submit the command buffer to the universal queue
@@ -1640,10 +1713,14 @@
     submit_info.pSignalSemaphores = NULL;
 
     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
-    ASSERT_VK_SUCCESS(err);
+    if (checkSuccess) {
+        ASSERT_VK_SUCCESS(err);
+    }
 
     err = vkQueueWaitIdle(m_device->m_queue);
-    ASSERT_VK_SUCCESS(err);
+    if (checkSuccess) {
+        ASSERT_VK_SUCCESS(err);
+    }
 
     // Wait for work to finish before cleaning up.
     vkDeviceWaitIdle(m_device->device());
@@ -1683,7 +1760,7 @@
 VkImageView *VkDepthStencilObj::BindInfo() { return &m_attachmentBindInfo; }
 
 void VkDepthStencilObj::Init(VkDeviceObj *device, int32_t width, int32_t height,
-                             VkFormat format) {
+                             VkFormat format, VkImageUsageFlags usage) {
 
     VkImageViewCreateInfo view_info = {};
 
@@ -1693,10 +1770,14 @@
 
     /* create image */
     init(width, height, m_depth_stencil_fmt,
-         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+         usage,
          VK_IMAGE_TILING_OPTIMAL);
 
-    SetLayout(VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+    VkImageAspectFlags aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
+    if (vk_format_is_depth_and_stencil(format))
+        aspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
+
+    SetLayout(aspect, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
 
     view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
     view_info.pNext = NULL;
diff --git a/tests/vkrenderframework.h b/tests/vkrenderframework.h
index 8871f68..4d71ae9 100644
--- a/tests/vkrenderframework.h
+++ b/tests/vkrenderframework.h
@@ -38,7 +38,6 @@
   public:
     VkDeviceObj(uint32_t id, VkPhysicalDevice obj);
     VkDeviceObj(uint32_t id, VkPhysicalDevice obj,
-                std::vector<const char *> &layers,
                 std::vector<const char *> &extension_names);
 
     VkDevice device() { return handle(); }
@@ -72,7 +71,6 @@
     void InitRenderTarget(uint32_t targets, VkImageView *dsBinding);
     void InitFramework();
     void InitFramework(std::vector<const char *> instance_layer_names,
-                       std::vector<const char *> device_layer_names,
                        std::vector<const char *> instance_extension_names,
                        std::vector<const char *> device_extension_names,
                        PFN_vkDebugReportCallbackEXT = NULL,
@@ -185,8 +183,8 @@
     void DrawIndexed(uint32_t indexCount, uint32_t instanceCount,
                      uint32_t firstIndex, int32_t vertexOffset,
                      uint32_t firstInstance);
-    void QueueCommandBuffer();
-    void QueueCommandBuffer(VkFence fence);
+    void QueueCommandBuffer(bool checkSuccess = true);
+    void QueueCommandBuffer(VkFence fence, bool checkSuccess = true);
     void SetViewport(uint32_t firstViewport, uint32_t viewportCount,
                      const VkViewport *pViewports);
     void SetScissor(uint32_t firstScissor, uint32_t scissorCount,
@@ -200,7 +198,7 @@
     void SetStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask);
     void SetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference);
     void UpdateBuffer(VkBuffer buffer, VkDeviceSize dstOffset,
-                      VkDeviceSize dataSize, const uint32_t *pData);
+                      VkDeviceSize dataSize, const void *pData);
     void CopyImage(VkImage srcImage, VkImageLayout srcImageLayout,
                    VkImage dstImage, VkImageLayout dstImageLayout,
                    uint32_t regionCount, const VkImageCopy *pRegions);
@@ -215,9 +213,15 @@
 
 class VkConstantBufferObj : public vk_testing::Buffer {
   public:
-    VkConstantBufferObj(VkDeviceObj *device);
+    VkConstantBufferObj(VkDeviceObj *device,
+                        VkBufferUsageFlags usage =
+            VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
+            VK_BUFFER_USAGE_TRANSFER_DST_BIT);
     VkConstantBufferObj(VkDeviceObj *device, int constantCount,
-                        int constantSize, const void *data);
+                        int constantSize, const void *data,
+                        VkBufferUsageFlags usage =
+            VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
+            VK_BUFFER_USAGE_TRANSFER_DST_BIT);
     ~VkConstantBufferObj();
     void BufferMemoryBarrier(
         VkFlags srcAccessMask = VK_ACCESS_HOST_WRITE_BIT |
@@ -272,6 +276,10 @@
               VkImageTiling tiling = VK_IMAGE_TILING_LINEAR,
               VkMemoryPropertyFlags reqs = 0);
 
+    void init_no_layout(uint32_t w, uint32_t h, VkFormat fmt, VkFlags usage,
+              VkImageTiling tiling = VK_IMAGE_TILING_LINEAR,
+              VkMemoryPropertyFlags reqs = 0);
+
     //    void clear( CommandBuffer*, uint32_t[4] );
 
     void layout(VkImageLayout layout) {
@@ -311,9 +319,9 @@
         return m_targetView.handle();
     }
 
-    void SetLayout(VkCommandBufferObj *cmd_buf, VkImageAspectFlagBits aspect,
+    void SetLayout(VkCommandBufferObj *cmd_buf, VkImageAspectFlags aspect,
                    VkImageLayout image_layout);
-    void SetLayout(VkImageAspectFlagBits aspect, VkImageLayout image_layout);
+    void SetLayout(VkImageAspectFlags aspect, VkImageLayout image_layout);
 
     VkImageLayout layout() const { return m_descriptorImageInfo.imageLayout; }
     uint32_t width() const { return extent().width; }
@@ -343,7 +351,7 @@
   public:
     VkDepthStencilObj(VkDeviceObj *device);
     void Init(VkDeviceObj *device, int32_t width, int32_t height,
-                       VkFormat format);
+                       VkFormat format, VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
     bool Initialized();
     VkImageView *BindInfo();
 
@@ -411,9 +419,9 @@
     VkPipelineObj(VkDeviceObj *device);
     void AddShader(VkShaderObj *shaderObj);
     void AddVertexInputAttribs(VkVertexInputAttributeDescription *vi_attrib,
-                               int count);
+                               uint32_t count);
     void AddVertexInputBindings(VkVertexInputBindingDescription *vi_binding,
-                                int count);
+                                uint32_t count);
     void AddColorAttachment(uint32_t binding,
                             const VkPipelineColorBlendAttachmentState *att);
     void MakeDynamic(VkDynamicState state);
@@ -453,5 +461,4 @@
     vector<VkPipelineColorBlendAttachmentState> m_colorAttachments;
     int m_vertexBufferCount;
 };
-
 #endif // VKRENDERFRAMEWORK_H
diff --git a/tests/vktestbinding.cpp b/tests/vktestbinding.cpp
index 8ef00d9..481df35 100644
--- a/tests/vktestbinding.cpp
+++ b/tests/vktestbinding.cpp
@@ -271,8 +271,7 @@
     vkDestroyDevice(handle(), NULL);
 }
 
-void Device::init(std::vector<const char *> &layers,
-                  std::vector<const char *> &extensions) {
+void Device::init(std::vector<const char *> &extensions) {
     // request all queues
     const std::vector<VkQueueFamilyProperties> queue_props =
         phy_.queue_properties();
@@ -302,8 +301,8 @@
     dev_info.pNext = NULL;
     dev_info.queueCreateInfoCount = queue_info.size();
     dev_info.pQueueCreateInfos = queue_info.data();
-    dev_info.enabledLayerCount = layers.size();
-    dev_info.ppEnabledLayerNames = layers.data();
+    dev_info.enabledLayerCount = 0;
+    dev_info.ppEnabledLayerNames = NULL;
     dev_info.enabledExtensionCount = extensions.size();
     dev_info.ppEnabledExtensionNames = extensions.data();
 
diff --git a/tests/vktestbinding.h b/tests/vktestbinding.h
index 6eb113c..c0667cb 100644
--- a/tests/vktestbinding.h
+++ b/tests/vktestbinding.h
@@ -148,13 +148,11 @@
 
     // vkCreateDevice()
     void init(const VkDeviceCreateInfo &info);
-    void init(std::vector<const char *> &layers,
-              std::vector<const char *> &
-                  extensions); // all queues, all extensions, etc
+    void init(std::vector<const char *>
+                  &extensions); // all queues, all extensions, etc
     void init() {
-        std::vector<const char *> layers;
         std::vector<const char *> extensions;
-        init(layers, extensions);
+        init(extensions);
     };
 
     const PhysicalDevice &phy() const { return phy_; }
diff --git a/tests/vktestframework.cpp b/tests/vktestframework.cpp
index 4e2bf04..ef8e4a2 100644
--- a/tests/vktestframework.cpp
+++ b/tests/vktestframework.cpp
@@ -224,7 +224,7 @@
     }
     printf("Error - device does not support VK_FORMAT_B8G8R8A8_UNORM nor "
            "VK_FORMAT_R8G8B8A8_UNORM - exiting\n");
-    exit(0);
+    exit(1);
 }
 
 void VkTestFramework::Finish() {}
@@ -598,7 +598,7 @@
 #endif
 
     char *fdata;
-    int count = 0;
+    size_t count = 0;
     const int maxSourceStrings = 5;
     char **return_data =
         (char **)malloc(sizeof(char *) * (maxSourceStrings + 1));
@@ -631,8 +631,8 @@
     } else
         m_num_shader_strings = 1;
 
-    int len = (int)(ceil)((float)count / (float)m_num_shader_strings);
-    int ptr_len = 0, i = 0;
+    size_t len = (int)(ceil)((float)count / (float)m_num_shader_strings);
+    size_t ptr_len = 0, i = 0;
     while (count > 0) {
         return_data[i] = (char *)malloc(len + 2);
         memcpy(return_data[i], fdata + ptr_len, len);
diff --git a/update_external_sources.bat b/update_external_sources.bat
old mode 100755
new mode 100644
index afe63d0..62bded1
--- a/update_external_sources.bat
+++ b/update_external_sources.bat
@@ -137,8 +137,10 @@
 
 set /p GLSLANG_REVISION= < glslang_revision
 set /p SPIRV_TOOLS_REVISION= < spirv-tools_revision
+set /p SPIRV_HEADERS_REVISION= < spirv-headers_revision
 echo GLSLANG_REVISION=%GLSLANG_REVISION%
 echo SPIRV_TOOLS_REVISION=%SPIRV_TOOLS_REVISION%
+echo SPIRV_HEADERS_REVISION=%SPIRV_HEADERS_REVISION%
 
 
 echo Creating and/or updating glslang, spirv-tools in %BASE_DIR%
@@ -215,6 +217,9 @@
    cd %GLSLANG_DIR%
    git fetch --all
    git checkout %GLSLANG_REVISION%
+   REM Revert glslang a5c33d6ffb34ccede5b233bc724c907166b6e479
+   REM See https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/681
+   git apply --whitespace=fix %BUILD_DIR%\glslang_revert_a5c33d.patch.txt
 goto:eof
 
 :create_spirv-tools
@@ -228,6 +233,15 @@
       echo spirv-tools source download failed!
       set errorCode=1
    )
+   mkdir %SPIRV_TOOLS_DIR%\external
+   mkdir %SPIRV_TOOLS_DIR%\external\spirv-headers
+   cd %SPIRV_TOOLS_DIR%\external\spirv-headers
+   git clone https://github.com/KhronosGroup/SPIRV-HEADERS.git .
+   git checkout %SPIRV_HEADERS_REVISION%
+   if not exist %SPIRV_TOOLS_DIR%\external\spirv-headers\README.md (
+      echo spirv-headers download failed!
+      set errorCode=1
+   )
 goto:eof
 
 :update_spirv-tools
@@ -236,6 +250,9 @@
    cd %SPIRV_TOOLS_DIR%
    git fetch --all
    git checkout %SPIRV_TOOLS_REVISION%
+   cd %SPIRV_TOOLS_DIR%\external\spirv-headers
+   git fetch --all
+   git checkout %SPIRV_HEADERS_REVISION%
 goto:eof
 
 :build_glslang
@@ -264,7 +281,7 @@
    msbuild INSTALL.vcxproj /p:Platform=x86 /p:Configuration=Debug /verbosity:quiet
    
    REM Check for existence of one lib, even though we should check for all results
-   if not exist %GLSLANG_BUILD_DIR%\glslang\Debug\glslang.lib (
+   if not exist %GLSLANG_BUILD_DIR%\glslang\Debug\glslangd.lib (
       echo.
       echo glslang 32-bit Debug build failed!
       set errorCode=1
@@ -294,7 +311,7 @@
    msbuild INSTALL.vcxproj /p:Platform=x64 /p:Configuration=Debug /verbosity:quiet
    
    REM Check for existence of one lib, even though we should check for all results
-   if not exist %GLSLANG_BUILD_DIR%\glslang\Debug\glslang.lib (
+   if not exist %GLSLANG_BUILD_DIR%\glslang\Debug\glslangd.lib (
       echo.
       echo glslang 64-bit Debug build failed!
       set errorCode=1
diff --git a/update_external_sources.sh b/update_external_sources.sh
index 4c1a6f9..59197f0 100755
--- a/update_external_sources.sh
+++ b/update_external_sources.sh
@@ -5,8 +5,10 @@
 
 GLSLANG_REVISION=$(cat $PWD/glslang_revision)
 SPIRV_TOOLS_REVISION=$(cat $PWD/spirv-tools_revision)
+SPIRV_HEADERS_REVISION=$(cat $PWD/spirv-headers_revision)
 echo "GLSLANG_REVISION=$GLSLANG_REVISION"
 echo "SPIRV_TOOLS_REVISION=$SPIRV_TOOLS_REVISION"
+echo "SPIRV_HEADERS_REVISION=$SPIRV_HEADERS_REVISION"
 
 BUILDDIR=$PWD
 BASEDIR=$BUILDDIR/external
@@ -25,6 +27,15 @@
    cd $BASEDIR/glslang
    git fetch --all
    git checkout $GLSLANG_REVISION
+   # Revert glslang a5c33d6ffb34ccede5b233bc724c907166b6e479
+   # See https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/681
+   git diff-index --quiet HEAD | true
+   rc=${PIPESTATUS[0]}
+   if (( $rc == 0 ))
+   then
+      echo "applying patch to revert glslang a5c33d"
+      git apply $BUILDDIR/glslang_revert_a5c33d.patch.txt
+   fi
 }
 
 function create_spirv-tools () {
@@ -34,6 +45,10 @@
    cd $BASEDIR/spirv-tools
    git clone https://github.com/KhronosGroup/SPIRV-Tools.git .
    git checkout $SPIRV_TOOLS_REVISION
+   mkdir -p $BASEDIR/spirv-tools/external/spirv-headers
+   cd $BASEDIR/spirv-tools/external/spirv-headers
+   git clone https://github.com/KhronosGroup/SPIRV-Headers .
+   git checkout $SPIRV_HEADERS_REVISION
 }
 
 function update_spirv-tools () {
@@ -41,6 +56,15 @@
    cd $BASEDIR/spirv-tools
    git fetch --all
    git checkout $SPIRV_TOOLS_REVISION
+   if [ ! -d "$BASEDIR/spirv-tools/external/spirv-headers" -o ! -d "$BASEDIR/spirv-tools/external/spirv-headers/.git" ]; then
+      mkdir -p $BASEDIR/spirv-tools/external/spirv-headers
+      cd $BASEDIR/spirv-tools/external/spirv-headers
+      git clone https://github.com/KhronosGroup/SPIRV-Headers .
+   else
+      cd $BASEDIR/spirv-tools/external/spirv-headers
+      git fetch --all
+   fi
+   git checkout $SPIRV_HEADERS_REVISION
 }
 
 function build_glslang () {
@@ -49,7 +73,6 @@
    mkdir -p build
    cd build
    cmake -D CMAKE_BUILD_TYPE=Release ..
-   cmake -D CMAKE_BUILD_TYPE=Release ..
    make
    make install
 }
diff --git a/vk-generate.py b/vk-generate.py
index c740494..c136c49 100755
--- a/vk-generate.py
+++ b/vk-generate.py
@@ -95,6 +95,12 @@
         pass
 
 class DispatchTableOpsSubcommand(Subcommand):
+    def __init__(self, argv):
+        self.argv = argv
+        self.headers = vulkan.headers_all
+        self.protos = vulkan.protos_all
+        self.outfile = None
+
     def run(self):
         if len(self.argv) < 1:
             print("DispatchTableOpsSubcommand: <prefix> unspecified")
@@ -121,13 +127,72 @@
         func = []
         if type == "device":
             # GPA has to be first one and uses wrapped object
-            stmts.append("memset(table, 0, sizeof(*table));")
-            stmts.append("table->GetDeviceProcAddr =(PFN_vkGetDeviceProcAddr)  gpa(device,\"vkGetDeviceProcAddr\");")
+            stmts.append("    memset(table, 0, sizeof(*table));")
+            stmts.append("    // Core device function pointers")
+            stmts.append("    table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) gpa(device, \"vkGetDeviceProcAddr\");")
+
+            KHR_printed = False
+            EXT_printed = False
+            Win32_printed = False
+            XLIB_printed = False
+            XCB_printed = False
+            MIR_printed = False
+            WAY_printed = False
+            Android_printed = False
             for proto in self.protos:
-                if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice":
+                if proto.name == "CreateInstance" or proto.name == "EnumerateInstanceExtensionProperties" or \
+                  proto.name == "EnumerateInstanceLayerProperties" or proto.params[0].ty == "VkInstance" or \
+                  proto.params[0].ty == "VkPhysicalDevice" or proto.name == "GetDeviceProcAddr":
                     continue
-                if proto.name != "GetDeviceProcAddr" and 'KHR' not in proto.name:
-                    stmts.append("table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" %
+                if Win32_printed and 'Win32' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_WIN32_KHR")
+                    Win32_printed = False
+                if XLIB_printed and 'Xlib' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_XLIB_KHR")
+                    XLIB_printed = False
+                if XCB_printed and 'Xcb' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_XCB_KHR")
+                    XCB_printed = False
+                if MIR_printed and 'Mir' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_MIR_KHR")
+                    MIR_printed = False
+                if WAY_printed and 'Wayland' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_WAYLAND_KHR")
+                    WAY_printed = False
+                if Android_printed and 'Android' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_ANDROID_KHR")
+                    Android_printed = False
+                if 'KHR' in proto.name and 'Win32' in proto.name:
+                    if not Win32_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_WIN32_KHR")
+                        Win32_printed = True
+                if 'KHR' in proto.name and 'Xlib' in proto.name:
+                    if not XLIB_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_XLIB_KHR")
+                        XLIB_printed = True
+                if 'KHR' in proto.name and 'Xcb' in proto.name:
+                    if not XCB_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_XCB_KHR")
+                        XCB_printed = True
+                if 'KHR' in proto.name and 'Mir' in proto.name:
+                    if not MIR_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_MIR_KHR")
+                        MIR_printed = True
+                if 'KHR' in proto.name and 'Wayland' in proto.name:
+                    if not WAY_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_WAYLAND_KHR")
+                        WAY_printed = True
+                if 'KHR' in proto.name and 'Android' in proto.name:
+                    if not Android_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_ANDROID_KHR")
+                        Android_printed = True
+                if 'KHR' in proto.name and not KHR_printed:
+                    stmts.append("    // KHR device extension function pointers")
+                    KHR_printed = True
+                if 'EXT' in proto.name and not EXT_printed:
+                    stmts.append("    // EXT device extension function pointers")
+                    EXT_printed = True
+                stmts.append("    table->%s = (PFN_vk%s) gpa(device, \"vk%s\");" %
                         (proto.name, proto.name, proto.name))
             func.append("static inline void %s_init_device_dispatch_table(VkDevice device,"
                 % self.prefix)
@@ -136,21 +201,78 @@
             func.append("%s                                               PFN_vkGetDeviceProcAddr gpa)"
                 % (" " * len(self.prefix)))
         else:
-            stmts.append("table->GetInstanceProcAddr =(PFN_vkGetInstanceProcAddr)  gpa(instance,\"vkGetInstanceProcAddr\");")
+            stmts.append("    memset(table, 0, sizeof(*table));")
+            stmts.append("    // Core instance function pointers")
+            stmts.append("    table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(instance, \"vkGetInstanceProcAddr\");")
+
+            KHR_printed = False
+            EXT_printed = False
+            Win32_printed = False
+            XLIB_printed = False
+            XCB_printed = False
+            MIR_printed = False
+            WAY_printed = False
+            Android_printed = False
             for proto in self.protos:
-                if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice":
+                if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice" or \
+                  proto.name == "CreateDevice" or proto.name == "GetInstanceProcAddr":
                     continue
-                if proto.name == "CreateDevice":
-                    continue
-                if proto.name != "GetInstanceProcAddr" and 'KHR' not in proto.name:
-                    stmts.append("table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
-                          (proto.name, proto.name, proto.name))
+                if Win32_printed and 'Win32' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_WIN32_KHR")
+                    Win32_printed = False
+                if XLIB_printed and 'Xlib' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_XLIB_KHR")
+                    XLIB_printed = False
+                if XCB_printed and 'Xcb' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_XCB_KHR")
+                    XCB_printed = False
+                if MIR_printed and 'Mir' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_MIR_KHR")
+                    MIR_printed = False
+                if WAY_printed and 'Wayland' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_WAYLAND_KHR")
+                    WAY_printed = False
+                if Android_printed and 'Android' not in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_ANDROID_KHR")
+                    Android_printed = False
+                if 'KHR' in proto.name and 'Win32' in proto.name:
+                    if not Win32_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_WIN32_KHR")
+                        Win32_printed = True
+                if 'KHR' in proto.name and 'Xlib' in proto.name:
+                    if not XLIB_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_XLIB_KHR")
+                        XLIB_printed = True
+                if 'KHR' in proto.name and 'Xcb' in proto.name:
+                    if not XCB_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_XCB_KHR")
+                        XCB_printed = True
+                if 'KHR' in proto.name and 'Mir' in proto.name:
+                    if not MIR_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_MIR_KHR")
+                        MIR_printed = True
+                if 'KHR' in proto.name and 'Wayland' in proto.name:
+                    if not WAY_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_WAYLAND_KHR")
+                        WAY_printed = True
+                if 'KHR' in proto.name and 'Android' in proto.name:
+                    if not Android_printed:
+                        stmts.append("#ifdef VK_USE_PLATFORM_ANDROID_KHR")
+                        Android_printed = True
+                if 'KHR' in proto.name and not KHR_printed:
+                    stmts.append("    // KHR instance extension function pointers")
+                    KHR_printed = True
+                if 'EXT' in proto.name and not EXT_printed:
+                    stmts.append("    // EXT instance extension function pointers")
+                    EXT_printed = True
+                stmts.append("    table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
+                      (proto.name, proto.name, proto.name))
             func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix)
             func.append("%s        VkInstance instance," % (" " * len(self.prefix)))
             func.append("%s        VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix)))
             func.append("%s        PFN_vkGetInstanceProcAddr gpa)" % (" " * len(self.prefix)))
         func.append("{")
-        func.append("    %s" % "\n    ".join(stmts))
+        func.append("%s" % "\n".join(stmts))
         func.append("}")
 
         return "\n".join(func)
@@ -243,7 +365,9 @@
             "Xcb",
             "Xlib",
             "Wayland",
-            "Mir"
+            "Mir",
+            "Display",
+            "AllPlatforms"
     }
     subcommands = {
             "dispatch-table-ops": DispatchTableOpsSubcommand,
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 24f3c93..5301e26 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python3
 #
 # VK
 #
@@ -54,7 +54,14 @@
         "GetPhysicalDeviceMirPresentationSupportKHR",
         "CreateAndroidSurfaceKHR",
         "CreateWin32SurfaceKHR",
-        "GetPhysicalDeviceWin32PresentationSupportKHR"
+        "GetPhysicalDeviceWin32PresentationSupportKHR",
+        "GetPhysicalDeviceDisplayPropertiesKHR",
+        "GetPhysicalDeviceDisplayPlanePropertiesKHR",
+        "GetDisplayPlaneSupportedDisplaysKHR",
+        "GetDisplayModePropertiesKHR",
+        "CreateDisplayModeKHR",
+        "GetDisplayPlaneCapabilitiesKHR",
+        "CreateDisplayPlaneSurfaceKHR"
     ]
     if proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice" or proto.name in global_function_names:
        return True
@@ -296,12 +303,13 @@
         r_body.append('        VkDebugReportCallbackEXT*                    pCallback)')
         r_body.append('{')
         # Switch to this code section for the new per-instance storage and debug callbacks
-        if self.layer_name in ['object_tracker', 'unique_objects']:
+        if self.layer_name in ['unique_objects']:
             r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
             r_body.append('    VkResult result = pInstanceTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);')
             r_body.append('    if (VK_SUCCESS == result) {')
             r_body.append('        layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);')
             r_body.append('        result = layer_create_msg_callback(my_data->report_data,')
+            r_body.append('                                           false,')
             r_body.append('                                           pCreateInfo,')
             r_body.append('                                           pAllocator,')
             r_body.append('                                           pCallback);')
@@ -311,7 +319,7 @@
             r_body.append('    VkResult result = instance_dispatch_table(instance)->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);')
             r_body.append('    if (VK_SUCCESS == result) {')
             r_body.append('        layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);')
-            r_body.append('        result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pCallback);')
+            r_body.append('        result = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pCallback);')
             r_body.append('    }')
             r_body.append('    return result;')
         r_body.append('}')
@@ -323,7 +331,7 @@
         r_body.append('VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, const VkAllocationCallbacks *pAllocator)')
         r_body.append('{')
         # Switch to this code section for the new per-instance storage and debug callbacks
-        if self.layer_name in ['object_tracker', 'unique_objects']:
+        if self.layer_name in ['unique_objects']:
             r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
         else:
             r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
@@ -339,10 +347,7 @@
         r_body.append('VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT    flags, VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg)')
         r_body.append('{')
         # Switch to this code section for the new per-instance storage and debug callbacks
-        if self.layer_name == 'object_tracker':
-            r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
-        else:
-            r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
+        r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
         r_body.append('    pInstanceTable->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);')
         r_body.append('}')
         return "\n".join(r_body)
@@ -375,50 +380,24 @@
     def _gen_layer_interface_v0_functions(self):
         body = []
         body.append('%s' % self.lineinfo.get())
-        body.append('// loader-layer interface v0')
+        body.append('// loader-layer interface v0, just wrappers since there is only a layer')
         body.append('')
 
-        if self.layer_name == 'object_tracker':
-            body.append('static const VkExtensionProperties instance_extensions[] = {')
-            body.append('    {')
-            body.append('        VK_EXT_DEBUG_REPORT_EXTENSION_NAME,')
-            body.append('        VK_EXT_DEBUG_REPORT_SPEC_VERSION')
-            body.append('    }')
-            body.append('};')
-            body.append('')
-
-            body.append('static const VkLayerProperties globalLayerProps = {')
-            body.append('    "VK_LAYER_LUNARG_%s",' % self.layer_name)
-            body.append('    VK_LAYER_API_VERSION, // specVersion')
-            body.append('    1, // implementationVersion')
-            body.append('    "LunarG Validation Layer"')
-            body.append('};')
-            body.append('')
-        else:
-            body.append('static const VkLayerProperties globalLayerProps = {')
-            body.append('    "VK_LAYER_GOOGLE_%s",' % self.layer_name)
-            body.append('    VK_LAYER_API_VERSION, // specVersion')
-            body.append('    1, // implementationVersion')
-            body.append('    "Google Validation Layer"')
-            body.append('};')
-            body.append('')
-
         body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,  VkExtensionProperties* pProperties)')
         body.append('{')
-        if self.layer_name == 'object_tracker':
-          body.append('    return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);')
-        else:
-          body.append('    return util_GetExtensionProperties(0, NULL, pCount, pProperties);')
+        body.append('    return %s::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);' % self.layer_name)
         body.append('}')
         body.append('')
         body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,  VkLayerProperties* pProperties)')
         body.append('{')
-        body.append('    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);')
+        body.append('    return %s::EnumerateInstanceLayerProperties(pCount, pProperties);' % self.layer_name)
         body.append('}')
         body.append('')
         body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties* pProperties)')
         body.append('{')
-        body.append('    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);')
+        body.append('    // the layer command handles VK_NULL_HANDLE just fine internally')
+        body.append('    assert(physicalDevice == VK_NULL_HANDLE);')
+        body.append('    return %s::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);' % self.layer_name)
         body.append('}')
         body.append('')
         body.append('VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName)')
@@ -428,17 +407,17 @@
         body.append('')
         body.append('VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName)')
         body.append('{')
-        body.append('    if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))')
-        body.append('        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties);')
-        body.append('    if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))')
-        body.append('        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties);')
-        body.append('    if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))')
-        body.append('        return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties);')
-        body.append('    if (!strcmp(funcName, "vkGetInstanceProcAddr"))')
-        body.append('        return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr);')
-        body.append('')
         body.append('    return %s::GetInstanceProcAddr(instance, funcName);' % self.layer_name)
         body.append('}')
+        body.append('')
+        body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,')
+        body.append('                                                                                    const char *pLayerName, uint32_t *pCount,')
+        body.append('                                                                                    VkExtensionProperties *pProperties)')
+        body.append('{')
+        body.append('    // the layer command handles VK_NULL_HANDLE just fine internally')
+        body.append('    assert(physicalDevice == VK_NULL_HANDLE);')
+        body.append('    return %s::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);' % self.layer_name)
+        body.append('}')
 
         return "\n".join(body)
 
@@ -451,11 +430,9 @@
         for proto in self.protos:
             if proto.name in ["EnumerateInstanceExtensionProperties",
                               "EnumerateInstanceLayerProperties",
-                              "EnumerateDeviceLayerProperties"]:
-                # the layer do not need to define these
-                continue
-            elif proto.name in ["GetDeviceProcAddr",
-                                "GetInstanceProcAddr"]:
+                              "EnumerateDeviceLayerProperties",
+                              "GetDeviceProcAddr",
+                              "GetInstanceProcAddr"]:
                 funcs.append(proto.c_func(attr="VKAPI") + ';')
                 intercepted.append(proto)
             else:
@@ -503,11 +480,6 @@
         body.append("{")
         body.append(generate_get_proc_addr_check("name"))
         body.append("")
-        body.append("    // we should never be queried for these commands")
-        body.append("    assert(strcmp(name, \"vkEnumerateInstanceLayerProperties\") &&")
-        body.append("           strcmp(name, \"vkEnumerateInstanceExtensionProperties\") &&")
-        body.append("           strcmp(name, \"vkEnumerateDeviceLayerProperties\"));")
-        body.append("")
         body.append("    name += 2;")
         body.append("    %s" % "\n    ".join(instance_lookups))
         body.append("")
@@ -525,12 +497,55 @@
         exts.append(self._gen_debug_report_msg())
         return "\n".join(exts)
 
+    def _generate_layer_introspection_function(self):
+        body = []
+        body.append('%s' % self.lineinfo.get())
+        body.append('static const VkLayerProperties globalLayerProps = {')
+        body.append('    "VK_LAYER_GOOGLE_%s",' % self.layer_name)
+        body.append('    VK_LAYER_API_VERSION, // specVersion')
+        body.append('    1, // implementationVersion')
+        body.append('    "Google Validation Layer"')
+        body.append('};')
+        body.append('')
+
+        body.append('VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount,  VkLayerProperties* pProperties)')
+        body.append('{')
+        body.append('    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);')
+        body.append('}')
+        body.append('')
+        body.append('VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties* pProperties)')
+        body.append('{')
+        body.append('    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);')
+        body.append('}')
+        body.append('')
+        body.append('VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,  VkExtensionProperties* pProperties)')
+        body.append('{')
+        body.append('    if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))')
+        body.append('        return util_GetExtensionProperties(0, NULL, pCount, pProperties);')
+        body.append('')
+        body.append('    return VK_ERROR_LAYER_NOT_PRESENT;')
+        body.append('}')
+        body.append('')
+        body.append('VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,')
+        body.append('                                                                  const char *pLayerName, uint32_t *pCount,')
+        body.append('                                                                  VkExtensionProperties *pProperties)')
+        body.append('{')
+        body.append('    if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))')
+        body.append('        return util_GetExtensionProperties(0, nullptr, pCount, pProperties);')
+        body.append('')
+        body.append('    assert(physicalDevice);')
+        body.append('    VkLayerInstanceDispatchTable* pTable = get_dispatch_table(%s_instance_table_map, physicalDevice);' % self.layer_name)
+        body.append('    return pTable->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);')
+        body.append('}')
+
+        return "\n".join(body)
+
     def _generate_layer_gpa_function(self, extensions=[], instance_extensions=[]):
         func_body = []
 #
 # New style of GPA Functions for the new layer_data/layer_logging changes
 #
-        if self.layer_name in ['object_tracker', 'unique_objects']:
+        if self.layer_name in ['unique_objects']:
             for ext_enable, ext_list in extensions:
                 func_body.append('%s' % self.lineinfo.get())
                 func_body.append('static inline PFN_vkVoidFunction intercept_%s_command(const char *name, VkDevice dev)' % ext_enable)
@@ -563,6 +578,14 @@
                              "    return get_dispatch_table(%s_device_table_map, device)->GetDeviceProcAddr(device, funcName);\n"
                              "}\n" % (self.layer_name, self.layer_name))
 
+            # The WSI-related extensions have independent extension enables
+            wsi_sub_enables = {'WIN32': 'win32_enabled',
+                               'XLIB': 'xlib_enabled',
+                               'XCB': 'xcb_enabled',
+                               'MIR': 'mir_enabled',
+                               'WAYLAND': 'wayland_enabled',
+                               'ANDROID': 'android_enabled'}
+
             for ext_enable, ext_list in instance_extensions:
                 func_body.append('%s' % self.lineinfo.get())
                 func_body.append('static inline PFN_vkVoidFunction intercept_%s_command(const char *name, VkInstance instance)' % ext_enable)
@@ -578,8 +601,12 @@
                     for ext_name in ext_list:
                         if wsi_name(ext_name):
                             func_body.append('%s' % wsi_ifdef(ext_name))
-                        func_body.append('    if (!strcmp("%s", name))\n'
-                                         '        return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (ext_name, ext_name[2:]))
+                            if wsi_sub_enables[wsi_name(ext_name)]:
+                                func_body.append('    if ((instanceExtMap[pTable].%s == true) && !strcmp("%s", name))\n'
+                                                 '        return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (wsi_sub_enables[wsi_name(ext_name)], ext_name, ext_name[2:]))
+                        else:
+                            func_body.append('    if (!strcmp("%s", name))\n'
+                                             '        return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (ext_name, ext_name[2:]))
                         if wsi_name(ext_name):
                             func_body.append('%s' % wsi_endif(ext_name))
 
@@ -716,655 +743,6 @@
         func_body.append('')
         return "\n".join(func_body)
 
-class ObjectTrackerSubcommand(Subcommand):
-    def generate_header(self):
-        header_txt = []
-        header_txt.append('%s' % self.lineinfo.get())
-        header_txt.append('#include "vk_loader_platform.h"')
-        header_txt.append('#include "vulkan/vulkan.h"')
-        header_txt.append('')
-        header_txt.append('#include <stdio.h>')
-        header_txt.append('#include <stdlib.h>')
-        header_txt.append('#include <string.h>')
-        header_txt.append('#include <cinttypes>')
-        header_txt.append('')
-        header_txt.append('#include <unordered_map>')
-        header_txt.append('')
-        header_txt.append('#include "vulkan/vk_layer.h"')
-        header_txt.append('#include "vk_layer_config.h"')
-        header_txt.append('#include "vk_layer_table.h"')
-        header_txt.append('#include "vk_layer_data.h"')
-        header_txt.append('#include "vk_layer_logging.h"')
-        header_txt.append('')
-#       NOTE:  The non-autoGenerated code is in the object_tracker.h header file
-        header_txt.append('#include "object_tracker.h"')
-        header_txt.append('')
-        return "\n".join(header_txt)
-
-    def generate_maps(self):
-        maps_txt = []
-        for o in vulkan.object_type_list:
-            maps_txt.append('std::unordered_map<uint64_t, OBJTRACK_NODE*> %sMap;' % (o))
-        return "\n".join(maps_txt)
-
-    def _gather_object_uses(self, obj_list, struct_type, obj_set):
-    # for each member of struct_type
-    #     add objs in obj_list to obj_set
-    #     call self for structs
-        for m in sorted(vk_helper.struct_dict[struct_type]):
-            if vk_helper.struct_dict[struct_type][m]['type'] in obj_list:
-                obj_set.add(vk_helper.struct_dict[struct_type][m]['type'])
-            elif vk_helper.is_type(vk_helper.struct_dict[struct_type][m]['type'], 'struct'):
-                obj_set = obj_set.union(self._gather_object_uses(obj_list, vk_helper.struct_dict[struct_type][m]['type'], obj_set))
-        return obj_set
-
-    def generate_procs(self):
-        procs_txt = []
-        # First parse through funcs and gather dict of all objects seen by each call
-        obj_use_dict = {}
-        proto_list = vulkan.core.protos + vulkan.ext_khr_surface.protos + vulkan.ext_khr_surface.protos + vulkan.ext_khr_win32_surface.protos + vulkan.ext_khr_device_swapchain.protos
-        for proto in proto_list:
-            disp_obj = proto.params[0].ty.strip('*').replace('const ', '')
-            if disp_obj in vulkan.object_dispatch_list:
-                if disp_obj not in obj_use_dict:
-                    obj_use_dict[disp_obj] = set()
-                for p in proto.params[1:]:
-                    base_type = p.ty.strip('*').replace('const ', '')
-                    if base_type in vulkan.object_type_list:
-                        obj_use_dict[disp_obj].add(base_type)
-                    if vk_helper.is_type(base_type, 'struct'):
-                        obj_use_dict[disp_obj] = self._gather_object_uses(vulkan.object_type_list, base_type, obj_use_dict[disp_obj])
-        #for do in obj_use_dict:
-        #    print "Disp obj %s has uses for objs: %s" % (do, ', '.join(obj_use_dict[do]))
-
-        for o in vulkan.object_type_list:# vulkan.core.objects:
-            procs_txt.append('%s' % self.lineinfo.get())
-            name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', o)
-            name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
-            if o in vulkan.object_dispatch_list:
-                procs_txt.append('static void create_%s(%s dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o, o))
-            else:
-                procs_txt.append('static void create_%s(VkDevice dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o))
-            procs_txt.append('{')
-            procs_txt.append('    log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType,(uint64_t)(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",')
-            procs_txt.append('        "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeEXT(objType),')
-            procs_txt.append('        (uint64_t)(vkObj));')
-            procs_txt.append('')
-            procs_txt.append('    OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;')
-            procs_txt.append('    pNewObjNode->belongsTo = (uint64_t)dispatchable_object;')
-            procs_txt.append('    pNewObjNode->objType = objType;')
-            procs_txt.append('    pNewObjNode->status  = OBJSTATUS_NONE;')
-            procs_txt.append('    pNewObjNode->vkObj  = (uint64_t)(vkObj);')
-            procs_txt.append('    %sMap[(uint64_t)vkObj] = pNewObjNode;' % (o))
-            procs_txt.append('    uint32_t objIndex = objTypeToIndex(objType);')
-            procs_txt.append('    numObjs[objIndex]++;')
-            procs_txt.append('    numTotalObjs++;')
-            procs_txt.append('}')
-            procs_txt.append('')
-            procs_txt.append('%s' % self.lineinfo.get())
-            if o in vulkan.object_dispatch_list:
-                procs_txt.append('static void destroy_%s(%s dispatchable_object, %s object)' % (name, o, o))
-            else:
-                procs_txt.append('static void destroy_%s(VkDevice dispatchable_object, %s object)' % (name, o))
-            procs_txt.append('{')
-            procs_txt.append('    uint64_t object_handle = (uint64_t)(object);')
-            procs_txt.append('    auto it = %sMap.find(object_handle);' % o)
-            procs_txt.append('    if (it != %sMap.end()) {' % o)
-            procs_txt.append('        OBJTRACK_NODE* pNode = it->second;')
-            procs_txt.append('        uint32_t objIndex = objTypeToIndex(pNode->objType);')
-            procs_txt.append('        assert(numTotalObjs > 0);')
-            procs_txt.append('        numTotalObjs--;')
-            procs_txt.append('        assert(numObjs[objIndex] > 0);')
-            procs_txt.append('        numObjs[objIndex]--;')
-            procs_txt.append('        log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_NONE, "OBJTRACK",')
-            procs_txt.append('           "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",')
-            procs_txt.append('            string_VkDebugReportObjectTypeEXT(pNode->objType), (uint64_t)(object), numTotalObjs, numObjs[objIndex],')
-            procs_txt.append('            string_VkDebugReportObjectTypeEXT(pNode->objType));')
-            procs_txt.append('        delete pNode;')
-            procs_txt.append('        %sMap.erase(it);' % (o))
-            procs_txt.append('    } else {')
-            procs_txt.append('        log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0,')
-            procs_txt.append('            object_handle, __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",')
-            procs_txt.append('            "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",')
-            procs_txt.append('            object_handle);')
-            procs_txt.append('    }')
-            procs_txt.append('}')
-            procs_txt.append('')
-        # Generate the permutations of validate_* functions where for each
-        #  dispatchable object type, we have a corresponding validate_* function
-        #  for that object and all non-dispatchable objects that are used in API
-        #  calls with that dispatchable object.
-        procs_txt.append('//%s' % str(sorted(obj_use_dict)))
-        for do in sorted(obj_use_dict):
-            name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', do)
-            name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
-            # First create validate_* func for disp obj
-            procs_txt.append('%s' % self.lineinfo.get())
-            procs_txt.append('static bool validate_%s(%s dispatchable_object, %s object, VkDebugReportObjectTypeEXT objType, bool null_allowed)' % (name, do, do))
-            procs_txt.append('{')
-            procs_txt.append('    if (null_allowed && (object == VK_NULL_HANDLE))')
-            procs_txt.append('        return false;')
-            procs_txt.append('    if (%sMap.find((uint64_t)object) == %sMap.end()) {' % (do, do))
-            procs_txt.append('        return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, objType, (uint64_t)(object), __LINE__, OBJTRACK_INVALID_OBJECT, "OBJTRACK",')
-            procs_txt.append('            "Invalid %s Object 0x%%" PRIx64 ,(uint64_t)(object));' % do)
-            procs_txt.append('    }')
-            procs_txt.append('    return false;')
-            procs_txt.append('}')
-            procs_txt.append('')
-            for o in sorted(obj_use_dict[do]):
-                if o == do: # We already generated this case above so skip here
-                    continue
-                name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', o)
-                name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
-                procs_txt.append('%s' % self.lineinfo.get())
-                procs_txt.append('static bool validate_%s(%s dispatchable_object, %s object, VkDebugReportObjectTypeEXT objType, bool null_allowed)' % (name, do, o))
-                procs_txt.append('{')
-                procs_txt.append('    if (null_allowed && (object == VK_NULL_HANDLE))')
-                procs_txt.append('        return false;')
-                if o == "VkImage":
-                    procs_txt.append('    // We need to validate normal image objects and those from the swapchain')
-                    procs_txt.append('    if ((%sMap.find((uint64_t)object) == %sMap.end()) &&' % (o, o))
-                    procs_txt.append('        (swapchainImageMap.find((uint64_t)object) == swapchainImageMap.end())) {')
-                else:
-                    procs_txt.append('    if (%sMap.find((uint64_t)object) == %sMap.end()) {' % (o, o))
-                procs_txt.append('        return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, objType, (uint64_t)(object), __LINE__, OBJTRACK_INVALID_OBJECT, "OBJTRACK",')
-                procs_txt.append('            "Invalid %s Object 0x%%" PRIx64, (uint64_t)(object));' % o)
-                procs_txt.append('    }')
-                procs_txt.append('    return false;')
-                procs_txt.append('}')
-            procs_txt.append('')
-        procs_txt.append('')
-        return "\n".join(procs_txt)
-
-    def generate_destroy_instance(self):
-        gedi_txt = []
-        gedi_txt.append('%s' % self.lineinfo.get())
-        gedi_txt.append('VKAPI_ATTR void VKAPI_CALL DestroyInstance(')
-        gedi_txt.append('VkInstance instance,')
-        gedi_txt.append('const VkAllocationCallbacks* pAllocator)')
-        gedi_txt.append('{')
-        gedi_txt.append('    std::unique_lock<std::mutex> lock(global_lock);')
-        gedi_txt.append('')
-        gedi_txt.append('    dispatch_key key = get_dispatch_key(instance);')
-        gedi_txt.append('    layer_data *my_data = get_my_data_ptr(key, layer_data_map);')
-        gedi_txt.append('')
-        gedi_txt.append('    // Enable the temporary callback(s) here to catch cleanup issues:')
-        gedi_txt.append('    bool callback_setup = false;')
-        gedi_txt.append('    if (my_data->num_tmp_callbacks > 0) {')
-        gedi_txt.append('        if (!layer_enable_tmp_callbacks(my_data->report_data,')
-        gedi_txt.append('                                        my_data->num_tmp_callbacks,')
-        gedi_txt.append('                                        my_data->tmp_dbg_create_infos,')
-        gedi_txt.append('                                        my_data->tmp_callbacks)) {')
-        gedi_txt.append('            callback_setup = true;')
-        gedi_txt.append('        }')
-        gedi_txt.append('    }')
-        gedi_txt.append('')
-        gedi_txt.append('    validate_instance(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);')
-        gedi_txt.append('')
-        gedi_txt.append('    destroy_instance(instance, instance);')
-        gedi_txt.append('    // Report any remaining objects in LL')
-        gedi_txt.append('')
-        gedi_txt.append('    for (auto iit = VkDeviceMap.begin(); iit != VkDeviceMap.end();) {')
-        gedi_txt.append('        OBJTRACK_NODE* pNode = iit->second;')
-        gedi_txt.append('        if (pNode->belongsTo == (uint64_t)instance) {')
-        gedi_txt.append('            log_msg(mid(instance), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
-        gedi_txt.append('                    "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
-        gedi_txt.append('                    pNode->vkObj);')
-        for o in vulkan.core.objects:
-            if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue', 'VkDevice']:
-                continue
-            gedi_txt.append('            for (auto idt = %sMap.begin(); idt != %sMap.end();) {' % (o, o))
-            gedi_txt.append('                OBJTRACK_NODE* pNode = idt->second;')
-            gedi_txt.append('                if (pNode->belongsTo == iit->first) {')
-            gedi_txt.append('                    log_msg(mid(instance), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
-            gedi_txt.append('                            "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
-            gedi_txt.append('                            pNode->vkObj);')
-            gedi_txt.append('                    %sMap.erase(idt++);' % o )
-            gedi_txt.append('                } else {')
-            gedi_txt.append('                    ++idt;')
-            gedi_txt.append('                }')
-            gedi_txt.append('            }')
-        gedi_txt.append('            VkDeviceMap.erase(iit++);')
-        gedi_txt.append('        } else {')
-        gedi_txt.append('            ++iit;')
-        gedi_txt.append('        }')
-        gedi_txt.append('    }')
-        gedi_txt.append('')
-        gedi_txt.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, instance);')
-        gedi_txt.append('    pInstanceTable->DestroyInstance(instance, pAllocator);')
-        gedi_txt.append('')
-        gedi_txt.append('    // Disable and cleanup the temporary callback(s):')
-        gedi_txt.append('    if (callback_setup) {')
-        gedi_txt.append('        layer_disable_tmp_callbacks(my_data->report_data,')
-        gedi_txt.append('                                    my_data->num_tmp_callbacks,')
-        gedi_txt.append('                                    my_data->tmp_callbacks);')
-        gedi_txt.append('    }')
-        gedi_txt.append('    if (my_data->num_tmp_callbacks > 0) {')
-        gedi_txt.append('        layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos,')
-        gedi_txt.append('                                 my_data->tmp_callbacks);')
-        gedi_txt.append('        my_data->num_tmp_callbacks = 0;')
-        gedi_txt.append('    }')
-        gedi_txt.append('')
-        gedi_txt.append('    // Clean up logging callback, if any')
-        gedi_txt.append('    while (my_data->logging_callback.size() > 0) {')
-        gedi_txt.append('        VkDebugReportCallbackEXT callback = my_data->logging_callback.back();')
-        gedi_txt.append('        layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);')
-        gedi_txt.append('        my_data->logging_callback.pop_back();')
-        gedi_txt.append('    }')
-        gedi_txt.append('')
-        gedi_txt.append('    layer_debug_report_destroy_instance(mid(instance));')
-        gedi_txt.append('    layer_data_map.erase(key);')
-        gedi_txt.append('')
-        gedi_txt.append('    instanceExtMap.erase(pInstanceTable);')
-        gedi_txt.append('    lock.unlock();')
-        # The loader holds a mutex that protects this from other threads
-        gedi_txt.append('    object_tracker_instance_table_map.erase(key);')
-        gedi_txt.append('}')
-        gedi_txt.append('')
-        return "\n".join(gedi_txt)
-
-    def generate_destroy_device(self):
-        gedd_txt = []
-        gedd_txt.append('%s' % self.lineinfo.get())
-        gedd_txt.append('VKAPI_ATTR void VKAPI_CALL DestroyDevice(')
-        gedd_txt.append('VkDevice device,')
-        gedd_txt.append('const VkAllocationCallbacks* pAllocator)')
-        gedd_txt.append('{')
-        gedd_txt.append('    std::unique_lock<std::mutex> lock(global_lock);')
-        gedd_txt.append('    validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);')
-        gedd_txt.append('')
-        gedd_txt.append('    destroy_device(device, device);')
-        gedd_txt.append('    // Report any remaining objects associated with this VkDevice object in LL')
-        for o in vulkan.core.objects:
-            # DescriptorSets and Command Buffers are destroyed through their pools, not explicitly
-            if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue', 'VkDevice', 'VkDescriptorSet', 'VkCommandBuffer']:
-                continue
-            gedd_txt.append('    for (auto it = %sMap.begin(); it != %sMap.end();) {' % (o, o))
-            gedd_txt.append('        OBJTRACK_NODE* pNode = it->second;')
-            gedd_txt.append('        if (pNode->belongsTo == (uint64_t)device) {')
-            gedd_txt.append('            log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
-            gedd_txt.append('                    "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
-            gedd_txt.append('                    pNode->vkObj);')
-            gedd_txt.append('            %sMap.erase(it++);' % o )
-            gedd_txt.append('        } else {')
-            gedd_txt.append('            ++it;')
-            gedd_txt.append('        }')
-            gedd_txt.append('    }')
-            gedd_txt.append('')
-        gedd_txt.append("    // Clean up Queue's MemRef Linked Lists")
-        gedd_txt.append('    destroyQueueMemRefLists();')
-        gedd_txt.append('')
-        gedd_txt.append('    lock.unlock();')
-        gedd_txt.append('')
-        gedd_txt.append('    dispatch_key key = get_dispatch_key(device);')
-        gedd_txt.append('    VkLayerDispatchTable *pDisp = get_dispatch_table(object_tracker_device_table_map, device);')
-        gedd_txt.append('    pDisp->DestroyDevice(device, pAllocator);')
-        gedd_txt.append('    object_tracker_device_table_map.erase(key);')
-        gedd_txt.append('')
-        gedd_txt.append('}')
-        gedd_txt.append('')
-        return "\n".join(gedd_txt)
-
-    # Special-case validating some objects -- they may be non-NULL but should
-    # only be validated upon meeting some condition specified below.
-    def _dereference_conditionally(self, indent, prefix, type_name, name):
-        s_code = ''
-        if type_name == 'pBufferInfo':
-            s_code += '%sif ((%sdescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)         ||\n'    % (indent, prefix)
-            s_code += '%s    (%sdescriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)         ||\n'    % (indent, prefix)
-            s_code += '%s    (%sdescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||\n'    % (indent, prefix)
-            s_code += '%s    (%sdescriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)   ) {\n' % (indent, prefix)
-        elif type_name == 'pImageInfo':
-            s_code += '%sif ((%sdescriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)                ||\n'    % (indent, prefix)
-            s_code += '%s    (%sdescriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||\n'    % (indent, prefix)
-            s_code += '%s    (%sdescriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)       ||\n'    % (indent, prefix)
-            s_code += '%s    (%sdescriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)          ||\n'    % (indent, prefix)
-            s_code += '%s    (%sdescriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)            ) {\n' % (indent, prefix)
-        elif type_name == 'pTexelBufferView':
-            s_code += '%sif ((%sdescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||\n'      % (indent, prefix)
-            s_code += '%s    (%sdescriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)   ) {\n'   % (indent, prefix)
-        elif name == 'pBeginInfo->pInheritanceInfo':
-            s_code += '%sOBJTRACK_NODE* pNode = VkCommandBufferMap[(uint64_t)commandBuffer];\n'       % (indent)
-            s_code += '%sif ((%s) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY)) {\n'       % (indent, name)
-        else:
-            s_code += '%sif (%s) {\n' % (indent, name)
-        return s_code
-
-    def _gen_obj_validate_code(self, struct_uses, obj_type_mapping, func_name, valid_null_dict, param0_name, indent, prefix, array_index):
-        pre_code = ''
-        for obj in sorted(struct_uses):
-            name = obj
-            array = ''
-            type_name = ''
-            if '[' in obj:
-                (name, array) = obj.split('[')
-                type_name = name
-                array = array.strip(']')
-            if isinstance(struct_uses[obj], dict):
-                local_prefix = ''
-                name = '%s%s' % (prefix, name)
-                ptr_type = False
-                if 'p' == obj[0]:
-                    ptr_type = True
-                    tmp_pre = self._dereference_conditionally(indent, prefix, type_name, name)
-                    pre_code += tmp_pre
-                    indent += '    '
-                if array != '':
-                    idx = 'idx%s' % str(array_index)
-                    array_index += 1
-                    pre_code += '%s\n' % self.lineinfo.get()
-                    pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx)
-                    indent += '    '
-                    local_prefix = '%s[%s].' % (name, idx)
-                elif ptr_type:
-                    local_prefix = '%s->' % (name)
-                else:
-                    local_prefix = '%s.' % (name)
-                tmp_pre = self._gen_obj_validate_code(struct_uses[obj], obj_type_mapping, func_name, valid_null_dict, param0_name, indent, local_prefix, array_index)
-                pre_code += tmp_pre
-                if array != '':
-                    indent = indent[4:]
-                    pre_code += '%s}\n' % (indent)
-                if ptr_type:
-                    indent = indent[4:]
-                    pre_code += '%s}\n' % (indent)
-            else:
-                ptype = struct_uses[obj]
-                dbg_obj_type = obj_type_mapping[ptype]
-                fname = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', ptype)
-                fname = re.sub('([a-z0-9])([A-Z])', r'\1_\2', fname).lower()[3:]
-                full_name = '%s%s' % (prefix, name)
-                null_obj_ok = 'false'
-                # If a valid null param is defined for this func and we have a match, allow NULL
-                if func_name in valid_null_dict and True in [name in pn for pn in sorted(valid_null_dict[func_name])]:
-                    null_obj_ok = 'true'
-                if (array_index > 0) or '' != array:
-                    tmp_pre = self._dereference_conditionally(indent, prefix, type_name, full_name)
-                    pre_code += tmp_pre
-                    indent += '    '
-                    if array != '':
-                        idx = 'idx%s' % str(array_index)
-                        array_index += 1
-                        pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx)
-                        indent += '    '
-                        full_name = '%s[%s]' % (full_name, idx)
-                    pre_code += '%s\n' % self.lineinfo.get()
-                    pre_code += '%sskipCall |= validate_%s(%s, %s, %s, %s);\n' %(indent, fname, param0_name, full_name, dbg_obj_type, null_obj_ok)
-                    if array != '':
-                        indent = indent[4:]
-                        pre_code += '%s}\n' % (indent)
-                    indent = indent[4:]
-                    pre_code += '%s}\n' % (indent)
-                else:
-                    pre_code += '%s\n' % self.lineinfo.get()
-                    pre_code += '%sskipCall |= validate_%s(%s, %s, %s, %s);\n' %(indent, fname, param0_name, full_name, dbg_obj_type, null_obj_ok)
-        return pre_code
-
-    def generate_intercept(self, proto, qual):
-        if proto.name in [ 'CreateDebugReportCallbackEXT', 'EnumerateInstanceLayerProperties', 'EnumerateInstanceExtensionProperties','EnumerateDeviceLayerProperties', 'EnumerateDeviceExtensionProperties' ]:
-            # use default version
-            return None
-
-        # Create map of object names to object type enums of the form VkName : VkObjectTypeName
-        obj_type_mapping = {base_t : base_t.replace("Vk", "VkDebugReportObjectType") for base_t in vulkan.object_type_list}
-        # Convert object type enum names from UpperCamelCase to UPPER_CASE_WITH_UNDERSCORES
-        for objectName, objectTypeEnum in obj_type_mapping.items():
-            obj_type_mapping[objectName] = ucc_to_U_C_C(objectTypeEnum) + '_EXT';
-        # Command Buffer Object doesn't follow the rule.
-        obj_type_mapping['VkCommandBuffer'] = "VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT"
-        obj_type_mapping['VkShaderModule'] = "VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT"
-
-        explicit_object_tracker_functions = [
-            "CreateInstance",
-            "EnumeratePhysicalDevices",
-            "GetPhysicalDeviceQueueFamilyProperties",
-            "CreateDevice",
-            "GetDeviceQueue",
-            "QueueBindSparse",
-            "AllocateDescriptorSets",
-            "FreeDescriptorSets",
-            "CreateGraphicsPipelines",
-            "CreateComputePipelines",
-            "AllocateCommandBuffers",
-            "FreeCommandBuffers",
-            "DestroyDescriptorPool",
-            "DestroyCommandPool",
-            "MapMemory",
-            "UnmapMemory",
-            "FreeMemory",
-            "DestroySwapchainKHR",
-            "GetSwapchainImagesKHR"
-        ]
-        decl = proto.c_func(attr="VKAPI")
-        param0_name = proto.params[0].name
-        using_line = ''
-        create_line = ''
-        destroy_line = ''
-        # Dict below tracks params that are vk objects. Dict is "loop count"->["params w/ that loop count"] where '0' is params that aren't in an array
-        # TODO : Should integrate slightly better code for this purpose from unique_objects layer
-        loop_params = defaultdict(list) # Dict uses loop count as key to make final code generation cleaner so params shared in single loop where needed
-        loop_types = defaultdict(list)
-        # TODO : For now skipping objs that can be NULL. Really should check these and have special case that allows them to be NULL
-        #  or better yet, these should be encoded into an API json definition and we generate checks from there
-        #  Until then, this is a dict where each func name is a list of object params that can be null (so don't need to be validated)
-        #   param names may be directly passed to the function, or may be a field in a struct param
-        valid_null_object_names = {'CreateGraphicsPipelines' : ['basePipelineHandle'],
-                                   'CreateComputePipelines' : ['basePipelineHandle'],
-                                   'BeginCommandBuffer' : ['renderPass', 'framebuffer'],
-                                   'QueueSubmit' : ['fence'],
-                                   'AcquireNextImageKHR' : ['fence', 'semaphore' ],
-                                   'UpdateDescriptorSets' : ['pTexelBufferView'],
-                                   'CreateSwapchainKHR' : ['oldSwapchain'],
-                                  }
-        param_count = 'NONE' # keep track of arrays passed directly into API functions
-        for p in proto.params:
-            base_type = p.ty.replace('const ', '').strip('*')
-            if 'count' in p.name.lower():
-                param_count = p.name
-            if base_type in vulkan.core.objects:
-                # This is an object to potentially check for validity. First see if it's an array
-                if '*' in p.ty and 'const' in p.ty and param_count != 'NONE':
-                    loop_params[param_count].append(p.name)
-                    loop_types[param_count].append(str(p.ty[6:-1]))
-                # Not an array, check for just a base Object that's not in exceptions
-                elif '*' not in p.ty and (proto.name not in valid_null_object_names or p.name not in valid_null_object_names[proto.name]):
-                    loop_params[0].append(p.name)
-                    loop_types[0].append(str(p.ty))
-            elif vk_helper.is_type(base_type, 'struct'):
-                struct_type = base_type
-                if vk_helper.typedef_rev_dict[struct_type] in vk_helper.struct_dict:
-                    struct_type = vk_helper.typedef_rev_dict[struct_type]
-                # Parse elements of this struct param to identify objects and/or arrays of objects
-                for m in sorted(vk_helper.struct_dict[struct_type]):
-                    if vk_helper.struct_dict[struct_type][m]['type'] in vulkan.core.objects and vk_helper.struct_dict[struct_type][m]['type'] not in ['VkPhysicalDevice', 'VkQueue', 'VkFence', 'VkImage', 'VkDeviceMemory']:
-                        if proto.name not in valid_null_object_names or vk_helper.struct_dict[struct_type][m]['name'] not in valid_null_object_names[proto.name]:
-                            # This is not great, but gets the job done for now, but If we have a count and this param is a ptr w/
-                            #  last letter 's' OR non-'count' string of count is in the param name, then this is a dynamically sized array param
-                            param_array = False
-                            if param_count != 'NONE':
-                                if '*' in p.ty:
-                                    if 's' == p.name[-1] or param_count.lower().replace('count', '') in p.name.lower():
-                                        param_array = True
-                            if param_array:
-                                param_name = '%s[i].%s' % (p.name, vk_helper.struct_dict[struct_type][m]['name'])
-                            else:
-                                param_name = '%s->%s' % (p.name, vk_helper.struct_dict[struct_type][m]['name'])
-                            if vk_helper.struct_dict[struct_type][m]['dyn_array']:
-                                if param_count != 'NONE': # this will be a double-embedded loop, use comma delineated 'count,name' for param_name
-                                    loop_count = '%s[i].%s' % (p.name, vk_helper.struct_dict[struct_type][m]['array_size'])
-                                    loop_params[param_count].append('%s,%s' % (loop_count, param_name))
-                                    loop_types[param_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type']))
-                                else:
-                                    loop_count = '%s->%s' % (p.name, vk_helper.struct_dict[struct_type][m]['array_size'])
-                                    loop_params[loop_count].append(param_name)
-                                    loop_types[loop_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type']))
-                            else:
-                                if '[' in param_name: # dynamic array param, set size
-                                    loop_params[param_count].append(param_name)
-                                    loop_types[param_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type']))
-                                else:
-                                    loop_params[0].append(param_name)
-                                    loop_types[0].append('%s' % (vk_helper.struct_dict[struct_type][m]['type']))
-        last_param_index = None
-        create_func = False
-        if True in [create_txt in proto.name for create_txt in ['Create', 'Allocate']]:
-            create_func = True
-            last_param_index = -1 # For create funcs don't validate last object
-        (struct_uses, local_decls) = get_object_uses(vulkan.object_type_list, proto.params[:last_param_index])
-        funcs = []
-        mutex_unlock = False
-        funcs.append('%s\n' % self.lineinfo.get())
-        if proto.name in explicit_object_tracker_functions:
-            funcs.append('%s%s\n'
-                     '{\n'
-                     '    return explicit_%s;\n'
-                     '}' % (qual, decl, proto.c_call()))
-            return "".join(funcs)
-        # Temporarily prevent  DestroySurface call from being generated until WSI layer support is fleshed out
-        elif 'DestroyInstance' in proto.name or 'DestroyDevice' in proto.name:
-            return ""
-        else:
-            if create_func:
-                typ = proto.params[-1].ty.strip('*').replace('const ', '');
-                name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ)
-                name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
-                create_line =  '    {\n'
-                create_line += '        std::lock_guard<std::mutex> lock(global_lock);\n'
-                create_line += '        if (result == VK_SUCCESS) {\n'
-                create_line += '            create_%s(%s, *%s, %s);\n' % (name, param0_name, proto.params[-1].name, obj_type_mapping[typ])
-                create_line += '        }\n'
-                create_line += '    }\n'
-            if 'FreeCommandBuffers' in proto.name:
-                typ = proto.params[-1].ty.strip('*').replace('const ', '');
-                name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ)
-                name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
-                funcs.append('%s\n' % self.lineinfo.get())
-                destroy_line =  '    loader_platform_thread_lock_mutex(&objLock);\n'
-                destroy_line += '    for (uint32_t i = 0; i < commandBufferCount; i++) {\n'
-                destroy_line += '        destroy_%s(%s[i], %s[i]);\n' % (name, proto.params[-1].name, proto.params[-1].name)
-                destroy_line += '    }\n'
-                destroy_line += '    loader_platform_thread_unlock_mutex(&objLock);\n'
-            if 'Destroy' in proto.name:
-                typ = proto.params[-2].ty.strip('*').replace('const ', '');
-                name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ)
-                name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
-                funcs.append('%s\n' % self.lineinfo.get())
-                destroy_line =  '    {\n'
-                destroy_line += '        std::lock_guard<std::mutex> lock(global_lock);\n'
-                destroy_line += '        destroy_%s(%s, %s);\n' % (name, param0_name, proto.params[-2].name)
-                destroy_line += '    }\n'
-            indent = '    '
-            if len(struct_uses) > 0:
-                using_line += '%sbool skipCall = false;\n' % (indent)
-                if not mutex_unlock:
-                    using_line += '%s{\n' % (indent)
-                    indent += '    '
-                    using_line += '%sstd::lock_guard<std::mutex> lock(global_lock);\n' % (indent)
-                    mutex_unlock = True
-                using_line += '// objects to validate: %s\n' % str(sorted(struct_uses))
-                using_line += self._gen_obj_validate_code(struct_uses, obj_type_mapping, proto.name, valid_null_object_names, param0_name, indent, '', 0)
-            if mutex_unlock:
-                indent = indent[4:]
-                using_line += '%s}\n' % (indent)
-            if len(struct_uses) > 0:
-                using_line += '    if (skipCall)\n'
-                if proto.ret == "bool":
-                    using_line += '        return false;\n'
-                elif proto.ret == "VkBool32":
-                    using_line += '        return VK_FALSE;\n'
-                elif proto.ret != "void":
-                    using_line += '        return VK_ERROR_VALIDATION_FAILED_EXT;\n'
-                else:
-                    using_line += '        return;\n'
-            ret_val = ''
-            stmt = ''
-            if proto.ret != "void":
-                ret_val = "%s result = " % proto.ret
-                stmt = "    return result;\n"
-
-            dispatch_param = proto.params[0].name
-            if 'CreateInstance' in proto.name:
-               dispatch_param = '*' + proto.params[1].name
-
-            # Must use 'instance' table for these APIs, 'device' table otherwise
-            table_type = ""
-            if proto_is_global(proto):
-                table_type = "instance"
-            else:
-                table_type = "device"
-            if wsi_name(proto.name):
-                funcs.append('%s' % wsi_ifdef(proto.name))
-            funcs.append('%s%s\n'
-                     '{\n'
-                     '%s'
-                     '%s'
-                     '    %sget_dispatch_table(object_tracker_%s_table_map, %s)->%s;\n'
-                     '%s'
-                     '%s'
-                     '}' % (qual, decl, using_line, destroy_line, ret_val, table_type, dispatch_param, proto.c_call(), create_line, stmt))
-            if wsi_name(proto.name):
-                funcs.append('%s' % wsi_endif(proto.name))
-        return "\n\n".join(funcs)
-
-    def generate_body(self):
-        self.layer_name = "object_tracker"
-        extensions=[('wsi_enabled',
-                     ['vkCreateSwapchainKHR',
-                      'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
-                      'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
-        if self.wsi == 'Win32':
-            instance_extensions=[('msg_callback_get_proc_addr', []),
-                                  ('wsi_enabled',
-                                  ['vkDestroySurfaceKHR',
-                                   'vkGetPhysicalDeviceSurfaceSupportKHR',
-                                   'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
-                                   'vkGetPhysicalDeviceSurfaceFormatsKHR',
-                                   'vkGetPhysicalDeviceSurfacePresentModesKHR',
-                                   'vkCreateWin32SurfaceKHR',
-                                   'vkGetPhysicalDeviceWin32PresentationSupportKHR'])]
-        elif self.wsi == 'Android':
-            instance_extensions=[('msg_callback_get_proc_addr', []),
-                                  ('wsi_enabled',
-                                  ['vkDestroySurfaceKHR',
-                                   'vkGetPhysicalDeviceSurfaceSupportKHR',
-                                   'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
-                                   'vkGetPhysicalDeviceSurfaceFormatsKHR',
-                                   'vkGetPhysicalDeviceSurfacePresentModesKHR',
-                                   'vkCreateAndroidSurfaceKHR'])]
-        elif self.wsi == 'Xcb' or self.wsi == 'Xlib' or self.wsi == 'Wayland' or self.wsi == 'Mir':
-            instance_extensions=[('msg_callback_get_proc_addr', []),
-                                  ('wsi_enabled',
-                                  ['vkDestroySurfaceKHR',
-                                   'vkGetPhysicalDeviceSurfaceSupportKHR',
-                                   'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
-                                   'vkGetPhysicalDeviceSurfaceFormatsKHR',
-                                   'vkGetPhysicalDeviceSurfacePresentModesKHR',
-                                   'vkCreateXcbSurfaceKHR',
-                                   'vkGetPhysicalDeviceXcbPresentationSupportKHR',
-                                   'vkCreateXlibSurfaceKHR',
-                                   'vkGetPhysicalDeviceXlibPresentationSupportKHR',
-                                   'vkCreateWaylandSurfaceKHR',
-                                   'vkGetPhysicalDeviceWaylandPresentationSupportKHR',
-                                   'vkCreateMirSurfaceKHR',
-                                   'vkGetPhysicalDeviceMirPresentationSupportKHR'])]
-        else:
-            print('Error: Undefined DisplayServer')
-            instance_extensions=[]
-
-        body = ["namespace %s {" % self.layer_name,
-                self.generate_maps(),
-                self.generate_procs(),
-                self.generate_destroy_instance(),
-                self.generate_destroy_device(),
-                self._generate_dispatch_entrypoints(),
-                self._generate_extensions(),
-                self._generate_layer_gpa_function(extensions,
-                                                  instance_extensions),
-                "} // namespace %s" % self.layer_name,
-                self._gen_layer_logging_workaround(),
-                self._gen_layer_interface_v0_functions()]
-        return "\n\n".join(body)
-
 class UniqueObjectsSubcommand(Subcommand):
     def generate_header(self):
         header_txt = []
@@ -1399,13 +777,17 @@
                         pre_code += '%sif (local_%s) {\n' % (indent, name)
                     indent += '    '
                 if array != '':
+                    if 'p' == array[0] and array[1] != array[1].lower(): # TODO : Not ideal way to determine ptr
+                        count_prefix = '*'
+                    else:
+                        count_prefix = ''
                     idx = 'idx%s' % str(array_index)
                     array_index += 1
                     if first_level_param and name in param_type:
-                        pre_code += '%slocal_%s = new safe_%s[%s];\n' % (indent, name, param_type[name].strip('*'), array)
+                        pre_code += '%slocal_%s = new safe_%s[%s%s];\n' % (indent, name, param_type[name].strip('*'), count_prefix, array)
                         post_code += '    if (local_%s)\n' % (name)
                         post_code += '        delete[] local_%s;\n' % (name)
-                    pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx)
+                    pre_code += '%sfor (uint32_t %s=0; %s<%s%s%s; ++%s) {\n' % (indent, idx, idx, count_prefix, prefix, array, idx)
                     indent += '    '
                     if first_level_param:
                         pre_code += '%slocal_%s[%s].initialize(&%s[%s]);\n' % (indent, name, idx, name, idx)
@@ -1448,7 +830,6 @@
                         pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx)
                         indent += '    '
                         name = '%s[%s]' % (name, idx)
-                    pName = 'p%s' % (struct_uses[obj][2:])
                     if name not in vector_name_set:
                         vector_name_set.add(name)
                     pre_code += '%slocal_%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s%s)];\n' % (indent, prefix, name, struct_uses[obj], prefix, name)
@@ -1459,9 +840,6 @@
                     pre_code += '%s}\n' % (indent)
                 else:
                     pre_code += '%s\n' % (self.lineinfo.get())
-                    deref_txt = '&'
-                    if ptr_type:
-                        deref_txt = ''
                     if '->' in prefix: # need to update local struct
                         pre_code += '%slocal_%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s%s)];\n' % (indent, prefix, name, struct_uses[obj], prefix, name)
                     else:
@@ -1479,14 +857,18 @@
         decl = proto.c_func(attr="VKAPI")
         # A few API cases that are manual code
         # TODO : Special case Create*Pipelines funcs to handle creating multiple unique objects
-        explicit_object_tracker_functions = ['GetSwapchainImagesKHR',
+        explicit_unique_objects_functions = ['GetSwapchainImagesKHR',
                                              'CreateSwapchainKHR',
                                              'CreateInstance',
                                              'DestroyInstance',
                                              'CreateDevice',
                                              'DestroyDevice',
+                                             'AllocateMemory',
                                              'CreateComputePipelines',
-                                             'CreateGraphicsPipelines'
+                                             'CreateGraphicsPipelines',
+                                             'GetPhysicalDeviceDisplayPropertiesKHR',
+                                             'GetDisplayPlaneSupportedDisplaysKHR',
+                                             'GetDisplayModePropertiesKHR'
                                              ]
         # TODO : This is hacky, need to make this a more general-purpose solution for all layers
         ifdef_dict = {'CreateXcbSurfaceKHR': 'VK_USE_PLATFORM_XCB_KHR',
@@ -1499,7 +881,7 @@
         # This dict stores array name and size of array
         custom_create_dict = {'pDescriptorSets' : 'pAllocateInfo->descriptorSetCount'}
         pre_call_txt += '%s\n' % (self.lineinfo.get())
-        if proto.name in explicit_object_tracker_functions:
+        if proto.name in explicit_unique_objects_functions:
             funcs.append('%s%s\n'
                      '{\n'
                      '    return explicit_%s;\n'
@@ -1529,6 +911,7 @@
                 for del_obj in sorted(struct_uses):
                     pre_call_txt += '%suint64_t local_%s = reinterpret_cast<uint64_t &>(%s);\n' % (indent, del_obj, del_obj)
                     pre_call_txt += '%s%s = (%s)my_map_data->unique_id_mapping[local_%s];\n' % (indent, del_obj, struct_uses[del_obj], del_obj)
+                pre_call_txt += '%smy_map_data->unique_id_mapping.erase(local_%s);\n' % (indent, proto.params[-2].name)
                 pre_call_txt += '%slock.unlock();\n' % (indent)
                 (pre_decl, pre_code, post_code) = ('', '', '')
             else:
@@ -1581,25 +964,15 @@
                     post_call_txt += '%s*%s = reinterpret_cast<%s&>(unique_id);\n' % (indent, obj_name, obj_type)
                 indent = indent[4:]
                 post_call_txt += '%s}\n' % (indent)
-        elif destroy_func:
-            del_obj = proto.params[-2].name
-            if 'count' in del_obj.lower():
-                post_call_txt += '%s\n' % (self.lineinfo.get())
-                post_call_txt += '%sfor (uint32_t i=0; i<%s; ++i) {\n' % (indent, del_obj)
-                del_obj = proto.params[-1].name
-                indent += '    '
-                post_call_txt += '%sdelete (VkUniqueObject*)%s[i];\n' % (indent, del_obj)
-                indent = indent[4:]
-                post_call_txt += '%s}\n' % (indent)
-            else:
-                post_call_txt += '%s\n' % (self.lineinfo.get())
-                post_call_txt += '%slock.lock();\n' % (indent)
-                post_call_txt += '%smy_map_data->unique_id_mapping.erase(local_%s);\n' % (indent, proto.params[-2].name)
 
         call_sig = proto.c_call()
         # Replace default params with any custom local params
         for ld in local_decls:
-            call_sig = call_sig.replace(ld, '(const %s)local_%s' % (local_decls[ld], ld))
+            const_qualifier = ''
+            for p in proto.params:
+                if ld == p.name and 'const' in p.ty:
+                    const_qualifier = 'const'
+            call_sig = call_sig.replace(ld, '(%s %s)local_%s' % (const_qualifier, local_decls[ld], ld))
         if proto_is_global(proto):
             table_type = "instance"
         else:
@@ -1627,41 +1000,41 @@
                      ['vkCreateSwapchainKHR',
                       'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
                       'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
+        surface_wsi_instance_exts = [
+                      'vkDestroySurfaceKHR',
+                      'vkGetPhysicalDeviceSurfaceSupportKHR',
+                      'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
+                      'vkGetPhysicalDeviceSurfaceFormatsKHR',
+                      'vkGetPhysicalDeviceSurfacePresentModesKHR']
+        display_wsi_instance_exts = [
+                      'vkGetPhysicalDeviceDisplayPropertiesKHR',
+                      'vkGetPhysicalDeviceDisplayPlanePropertiesKHR',
+                      'vkGetDisplayPlaneSupportedDisplaysKHR',
+                      'vkGetDisplayModePropertiesKHR',
+                      'vkCreateDisplayModeKHR',
+                      'vkGetDisplayPlaneCapabilitiesKHR',
+                      'vkCreateDisplayPlaneSurfaceKHR']
         if self.wsi == 'Win32':
-            instance_extensions=[('wsi_enabled',
-                                  ['vkDestroySurfaceKHR',
-                                   'vkGetPhysicalDeviceSurfaceSupportKHR',
-                                   'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
-                                   'vkGetPhysicalDeviceSurfaceFormatsKHR',
-                                   'vkGetPhysicalDeviceSurfacePresentModesKHR',
-                                   'vkCreateWin32SurfaceKHR'
-                                   ])]
+            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
+                                 ('display_enabled', display_wsi_instance_exts),
+                                 ('win32_enabled', ['vkCreateWin32SurfaceKHR'])]
         elif self.wsi == 'Android':
-            instance_extensions=[('wsi_enabled',
-                                  ['vkDestroySurfaceKHR',
-                                   'vkGetPhysicalDeviceSurfaceSupportKHR',
-                                   'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
-                                   'vkGetPhysicalDeviceSurfaceFormatsKHR',
-                                   'vkGetPhysicalDeviceSurfacePresentModesKHR',
-                                   'vkCreateAndroidSurfaceKHR'])]
+            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
+                                 ('android_enabled', ['vkCreateAndroidSurfaceKHR'])]
         elif self.wsi == 'Xcb' or self.wsi == 'Xlib' or self.wsi == 'Wayland' or self.wsi == 'Mir':
-            instance_extensions=[('wsi_enabled',
-                                  ['vkDestroySurfaceKHR',
-                                   'vkGetPhysicalDeviceSurfaceSupportKHR',
-                                   'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
-                                   'vkGetPhysicalDeviceSurfaceFormatsKHR',
-                                   'vkGetPhysicalDeviceSurfacePresentModesKHR',
-                                   'vkCreateXcbSurfaceKHR',
-                                   'vkCreateXlibSurfaceKHR',
-                                   'vkCreateWaylandSurfaceKHR',
-                                   'vkCreateMirSurfaceKHR'
-                                   ])]
+            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
+                                 ('display_enabled', display_wsi_instance_exts),
+                                 ('xcb_enabled', ['vkCreateXcbSurfaceKHR']),
+                                 ('xlib_enabled', ['vkCreateXlibSurfaceKHR']),
+                                 ('wayland_enabled',  ['vkCreateWaylandSurfaceKHR']),
+                                 ('mir_enabled', ['vkCreateMirSurfaceKHR'])]
         else:
             print('Error: Undefined DisplayServer')
             instance_extensions=[]
 
         body = ["namespace %s {" % self.layer_name,
                 self._generate_dispatch_entrypoints(),
+                self._generate_layer_introspection_function(),
                 self._generate_layer_gpa_function(extensions,
                                                   instance_extensions),
                 "} // namespace %s" % self.layer_name,
@@ -1679,7 +1052,6 @@
     }
 
     subcommands = {
-            "object_tracker" : ObjectTrackerSubcommand,
             "unique_objects" : UniqueObjectsSubcommand,
     }
 
diff --git a/vk-layer-introspect b/vk-layer-introspect
new file mode 100755
index 0000000..e64373e
--- /dev/null
+++ b/vk-layer-introspect
@@ -0,0 +1,399 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2016 Google Inc.
+#
+# Licensed under the Apache 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
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+import argparse
+import ctypes
+import json
+import os
+import platform
+import sys
+import xml.etree.ElementTree
+
+if platform.system() == "Windows":
+    VKAPI_DLL = ctypes.windll
+    VKAPI_FUNCTYPE = ctypes.WINFUNCTYPE
+else:
+    VKAPI_DLL = ctypes.cdll
+    VKAPI_FUNCTYPE = ctypes.CFUNCTYPE
+
+# Vulkan types
+
+VkInstance = ctypes.c_void_p
+VkPhysicalDevice = ctypes.c_void_p
+VkDevice = ctypes.c_void_p
+VkResult = ctypes.c_int
+
+
+class VkLayerProperties(ctypes.Structure):
+    _fields_ = [("c_layerName", ctypes.c_char * 256),
+                ("c_specVersion", ctypes.c_uint32),
+                ("c_implementationVersion", ctypes.c_uint32),
+                ("c_description", ctypes.c_char * 256)]
+
+    def layer_name(self):
+        return self.c_layerName.decode()
+
+    def spec_version(self):
+        return "%d.%d.%d" % (
+            self.c_specVersion >> 22,
+            (self.c_specVersion >> 12) & 0x3ff,
+            self.c_specVersion & 0xfff)
+
+    def implementation_version(self):
+        return str(self.c_implementationVersion)
+
+    def description(self):
+        return self.c_description.decode()
+
+    def __eq__(self, other):
+        return (self.c_layerName == other.c_layerName and
+                self.c_specVersion == other.c_specVersion and
+                self.c_implementationVersion == other.c_implementationVersion and
+                self.c_description == other.c_description)
+
+
+class VkExtensionProperties(ctypes.Structure):
+    _fields_ = [("c_extensionName", ctypes.c_char * 256),
+                ("c_specVersion", ctypes.c_uint32)]
+
+    def extension_name(self):
+        return self.c_extensionName.decode()
+
+    def spec_version(self):
+        return str(self.c_specVersion)
+
+# Vulkan commands
+
+PFN_vkVoidFunction = VKAPI_FUNCTYPE(None)
+PFN_vkEnumerateInstanceExtensionProperties = VKAPI_FUNCTYPE(
+    VkResult, ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(VkExtensionProperties))
+PFN_vkEnumerateDeviceExtensionProperties = VKAPI_FUNCTYPE(
+    VkResult, VkPhysicalDevice, ctypes.c_char_p, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(VkExtensionProperties))
+PFN_vkEnumerateInstanceLayerProperties = VKAPI_FUNCTYPE(
+    VkResult, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(VkLayerProperties))
+PFN_vkEnumerateDeviceLayerProperties = VKAPI_FUNCTYPE(
+    VkResult, VkPhysicalDevice, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(VkLayerProperties))
+PFN_vkGetInstanceProcAddr = VKAPI_FUNCTYPE(
+    PFN_vkVoidFunction, VkInstance, ctypes.c_char_p)
+PFN_vkGetDeviceProcAddr = VKAPI_FUNCTYPE(
+    PFN_vkVoidFunction, VkDevice, ctypes.c_char_p)
+
+
+class Layer(object):
+
+    def __init__(self, *args):
+        self.props = args[0]
+        self.is_global = args[1]
+        self.instance_extensions = args[2]
+        self.device_extensions = args[3]
+        self.gipa_name = args[4]
+        self.gdpa_name = args[5]
+
+
+class LayerLibrary(object):
+
+    def __init__(self, path):
+        self.library = None
+        self.version = 0
+
+        self._load(path)
+        self._negotiate_version()
+
+    def introspect(self):
+        if self.version == 0:
+            layers = self._enumerate_layers_v0()
+        else:
+            raise RuntimeError("unsupported v%d library" % self.version)
+
+        return layers
+
+    def _load(self, path):
+        try:
+            abspath = os.path.abspath(path)
+            self.library = VKAPI_DLL.LoadLibrary(abspath)
+        except OSError:
+            raise RuntimeError("failed to load library")
+
+    def _unload(self):
+        # no clean way to unload
+        pass
+
+    def _negotiate_version(self):
+        # only v0
+        self.version = 0
+
+    def _enumerate_properties_errcheck_v0(self, result, func, args):
+        if isinstance(func, PFN_vkEnumerateInstanceLayerProperties):
+            func_name = "vkEnumerateInstanceLayerProperties"
+        elif isinstance(func, PFN_vkEnumerateDeviceLayerProperties):
+            func_name = "vkEnumerateDeviceLayerProperties"
+        elif isinstance(func, PFN_vkEnumerateInstanceExtensionProperties):
+            func_name = "vkEnumerateInstanceExtensionProperties"
+        elif isinstance(func, PFN_vkEnumerateDeviceExtensionProperties):
+            func_name = "vkEnumerateDeviceExtensionProperties"
+        else:
+            raise AssertionError("unexpected vkEnumerate*Properties call")
+
+        if result != 0:
+            raise RuntimeError(func_name + " failed with " + str(result))
+
+        # pProperties and pCount mismatch
+        if args[-1] and len(args[-1]) != args[-2].value:
+            raise RuntimeError("invalid pCount returned in " + func_name)
+
+        return args[-1]
+
+    def _enumerate_properties_prototype_v0(self, func_name):
+        prototypes = {
+            "vkEnumerateInstanceLayerProperties":
+            PFN_vkEnumerateInstanceLayerProperties,
+            "vkEnumerateDeviceLayerProperties":
+            PFN_vkEnumerateDeviceLayerProperties,
+            "vkEnumerateInstanceExtensionProperties":
+            PFN_vkEnumerateInstanceExtensionProperties,
+            "vkEnumerateDeviceExtensionProperties":
+            PFN_vkEnumerateDeviceExtensionProperties,
+        }
+        prototype = prototypes[func_name]
+
+        try:
+            proc = prototype((func_name, self.library))
+        except AttributeError:
+            raise RuntimeError(func_name + " is missing")
+
+        proc.errcheck = self._enumerate_properties_errcheck_v0
+
+        return proc
+
+    def _get_gipa_name_v0(self, layer_name, can_fallback):
+        names = [layer_name + "GetInstanceProcAddr"]
+        if can_fallback:
+            names.append("vkGetInstanceProcAddr")
+
+        for name in names:
+            try:
+                PFN_vkGetInstanceProcAddr((name, self.library))
+                return name
+            except AttributeError:
+                pass
+
+        raise RuntimeError(" or ".join(names) + " is missing")
+
+    def _get_gdpa_name_v0(self, layer_name, can_fallback):
+        names = [layer_name + "GetDeviceProcAddr"]
+        if can_fallback:
+            names.append("vkGetDeviceProcAddr")
+
+        for name in names:
+            try:
+                PFN_vkGetDeviceProcAddr((name, self.library))
+                return name
+            except AttributeError:
+                pass
+
+        raise RuntimeError(" or ".join(names) + " is missing")
+
+    def _enumerate_layers_v0(self):
+        tmp_count = ctypes.c_uint32()
+
+        # enumerate instance layers
+        enumerate_instance_layer_properties = self._enumerate_properties_prototype_v0(
+            "vkEnumerateInstanceLayerProperties")
+        enumerate_instance_layer_properties(tmp_count, None)
+        p_props = enumerate_instance_layer_properties(
+            tmp_count, (VkLayerProperties * tmp_count.value)())
+
+        # enumerate device layers
+        enumerate_device_layer_properties = self._enumerate_properties_prototype_v0(
+            "vkEnumerateDeviceLayerProperties")
+        enumerate_device_layer_properties(None, tmp_count, None)
+        dev_p_props = enumerate_device_layer_properties(
+            None, tmp_count, (VkLayerProperties * tmp_count.value)())
+
+        # there must not be device-only layers
+        for props in dev_p_props:
+            if props not in p_props:
+                raise RuntimeError(
+                    "unexpected device-only layer " + props.layer_name())
+
+        layers = []
+        for props in p_props:
+            is_global = (props in dev_p_props)
+
+            # enumerate instance extensions
+            enumerate_instance_extension_properties = self._enumerate_properties_prototype_v0(
+                "vkEnumerateInstanceExtensionProperties")
+            enumerate_instance_extension_properties(
+                props.c_layerName, tmp_count, None)
+            instance_extensions = enumerate_instance_extension_properties(
+                props.c_layerName,
+                tmp_count,
+                (VkExtensionProperties * tmp_count.value)())
+
+            gipa_name = self._get_gipa_name_v0(
+                props.layer_name(),
+                len(p_props) == 1)
+
+            if is_global:
+                # enumerate device extensions
+                enumerate_device_extension_properties = self._enumerate_properties_prototype_v0(
+                    "vkEnumerateDeviceExtensionProperties")
+                enumerate_device_extension_properties(
+                    None, props.c_layerName, tmp_count, None)
+                device_extensions = enumerate_device_extension_properties(
+                    None,
+                    props.c_layerName,
+                    tmp_count,
+                    (VkExtensionProperties * tmp_count.value)())
+
+                gdpa_name = self._get_gdpa_name_v0(
+                    props.layer_name(),
+                    len(p_props) == 1)
+            else:
+                device_extensions = None
+                gdpa_name = None
+
+            layers.append(
+                Layer(props, is_global, instance_extensions, device_extensions, gipa_name, gdpa_name))
+
+        return layers
+
+
+def serialize_layers(layers, path, ext_cmds):
+    data = {}
+    data["file_format_version"] = '1.0.0'
+
+    for idx, layer in enumerate(layers):
+        layer_data = {}
+
+        layer_data["name"] = layer.props.layer_name()
+        layer_data["api_version"] = layer.props.spec_version()
+        layer_data[
+            "implementation_version"] = layer.props.implementation_version()
+        layer_data["description"] = layer.props.description()
+
+        layer_data["type"] = "GLOBAL" if layer.is_global else "INSTANCE"
+
+        # TODO more flexible
+        layer_data["library_path"] = os.path.join(".", os.path.basename(path))
+
+        funcs = {}
+        if layer.gipa_name != "vkGetInstanceProcAddr":
+            funcs["vkGetInstanceProcAddr"] = layer.gipa_name
+        if layer.is_global and layer.gdpa_name != "vkGetDeviceProcAddr":
+            funcs["vkGetDeviceProcAddr"] = layer.gdpa_name
+        if funcs:
+            layer_data["functions"] = funcs
+
+        if layer.instance_extensions:
+            exts = [{
+                "name": ext.extension_name(),
+                "spec_version": ext.spec_version(),
+            } for ext in layer.instance_extensions]
+            layer_data["instance_extensions"] = exts
+
+        if layer.device_extensions:
+            exts = []
+            for ext in layer.device_extensions:
+                try:
+                    cmds = ext_cmds[ext.extension_name()]
+                except KeyError:
+                    raise RuntimeError(
+                        "unknown device extension " + ext.extension_name())
+                else:
+                    ext_data = {}
+                    ext_data["name"] = ext.extension_name()
+                    ext_data["spec_version"] = ext.spec_version()
+                    if cmds:
+                        ext_data["entrypoints"] = cmds
+
+                    exts.append(ext_data)
+
+            layer_data["device_extensions"] = exts
+
+        if idx > 0:
+            data["layer.%d" % idx] = layer_data
+        else:
+            data["layer"] = layer_data
+
+    return data
+
+
+def dump_json(data):
+    dump = json.dumps(data, indent=4, sort_keys=True)
+
+    # replace "layer.<idx>" by "layer"
+    lines = dump.split("\n")
+    for line in lines:
+        if line.startswith("    \"layer.") and line.endswith("\": {"):
+            line = "    \"layer\": {"
+        print(line)
+
+
+def parse_vk_xml(path):
+    """Parse vk.xml to get commands added by extensions."""
+    tree = xml.etree.ElementTree.parse(path)
+    extensions = tree.find("extensions")
+
+    ext_cmds = {}
+    for ext in extensions.iter("extension"):
+        if ext.attrib["supported"] != "vulkan":
+            continue
+
+        cmds = []
+        for cmd in ext.iter("command"):
+            cmds.append(cmd.attrib["name"])
+
+        ext_cmds[ext.attrib["name"]] = cmds
+
+    return ext_cmds
+
+
+def add_custom_ext_cmds(ext_cmds):
+    """Add commands added by in-development extensions."""
+    # VK_LAYER_LUNARG_basic
+    ext_cmds["vkLayerBasicEXT"] = ["vkLayerBasicEXT"]
+
+
+def main():
+    default_vk_xml = sys.path[0] + "/vk.xml" if sys.path[0] else "vk.xml"
+
+    parser = argparse.ArgumentParser(description="Introspect a layer library.")
+    parser.add_argument(
+        "-x", dest="vk_xml", default=default_vk_xml, help="Path to vk.xml")
+    parser.add_argument(
+        "layer_libs", metavar="layer-lib", nargs="+", help="Path to a layer library")
+    args = parser.parse_args()
+
+    try:
+        ext_cmds = parse_vk_xml(args.vk_xml)
+    except Exception as e:
+        print("failed to parse %s: %s" % (args.vk_xml, e))
+        sys.exit(-1)
+
+    add_custom_ext_cmds(ext_cmds)
+
+    for path in args.layer_libs:
+        try:
+            ll = LayerLibrary(path)
+            layers = ll.introspect()
+            data = serialize_layers(layers, path, ext_cmds)
+            dump_json(data)
+        except RuntimeError as err:
+            print("skipping %s: %s" % (path, err))
+
+if __name__ == "__main__":
+    main()
diff --git a/vk.xml b/vk.xml
index b179211..00c0e62 100644
--- a/vk.xml
+++ b/vk.xml
@@ -101,7 +101,7 @@
         <type category="define">// Vulkan 1.0 version number
 #define <name>VK_API_VERSION_1_0</name> <type>VK_MAKE_VERSION</type>(1, 0, 0)</type>    <!-- The patch version here should never be set to anything other than 0 -->
         <type category="define">// Version of this file
-#define <name>VK_HEADER_VERSION</name> 13</type>
+#define <name>VK_HEADER_VERSION</name> 21</type>
 
         <type category="define">
 #define <name>VK_DEFINE_HANDLE</name>(object) typedef struct object##_T* object;</type>
@@ -131,7 +131,7 @@
         <type requires="vk_platform" name="uint64_t"/>
         <type requires="vk_platform" name="int32_t"/>
         <type requires="vk_platform" name="size_t"/>
-        <!-- Bitfield types -->
+        <!-- Bitmask types -->
         <type                                             category="bitmask">typedef <type>VkFlags</type> <name>VkFramebufferCreateFlags</name>;</type>               <!-- creation flags -->
         <type                                             category="bitmask">typedef <type>VkFlags</type> <name>VkQueryPoolCreateFlags</name>;</type>                 <!-- creation flags -->
         <type                                             category="bitmask">typedef <type>VkFlags</type> <name>VkRenderPassCreateFlags</name>;</type>                <!-- creation flags -->
@@ -178,7 +178,7 @@
         <type requires="VkCommandBufferUsageFlagBits"         category="bitmask">typedef <type>VkFlags</type> <name>VkCommandBufferUsageFlags</name>;</type>              <!-- Command buffer usage flags -->
         <type requires="VkQueryPipelineStatisticFlagBits" category="bitmask">typedef <type>VkFlags</type> <name>VkQueryPipelineStatisticFlags</name>;</type>      <!-- Pipeline statistics flags -->
         <type                                             category="bitmask">typedef <type>VkFlags</type> <name>VkMemoryMapFlags</name>;</type>                   <!-- Memory mapping flags (no bits yet) -->
-        <type requires="VkImageAspectFlagBits"            category="bitmask">typedef <type>VkFlags</type> <name>VkImageAspectFlags</name>;</type>                 <!-- Bitfield of image aspects -->
+        <type requires="VkImageAspectFlagBits"            category="bitmask">typedef <type>VkFlags</type> <name>VkImageAspectFlags</name>;</type>                 <!-- Bitmask of image aspects -->
         <type requires="VkSparseMemoryBindFlagBits"       category="bitmask">typedef <type>VkFlags</type> <name>VkSparseMemoryBindFlags</name>;</type>            <!-- Sparse memory bind flags -->
         <type requires="VkSparseImageFormatFlagBits"      category="bitmask">typedef <type>VkFlags</type> <name>VkSparseImageFormatFlags</name>;</type>           <!-- Sparse image memory requirements flags -->
         <type                                             category="bitmask">typedef <type>VkFlags</type> <name>VkSubpassDescriptionFlags</name>;</type>          <!-- Subpass description flags -->
@@ -505,9 +505,6 @@
             <member len="enabledExtensionCount,null-terminated">const <type>char</type>* const*      <name>ppEnabledExtensionNames</name></member>
             <member optional="true">const <type>VkPhysicalDeviceFeatures</type>* <name>pEnabledFeatures</name></member>
             <validity>
-                <usage>pname:ppEnabledLayerNames must: either be sname:NULL or contain the same sequence of layer names that was enabled when creating the parent instance</usage>
-                <usage>Any given element of pname:ppEnabledExtensionNames must: be the name of an extension present on the system, exactly matching a string returned in the sname:VkExtensionProperties structure by fname:vkEnumerateDeviceExtensionProperties</usage>
-                <usage>If an extension listed in pname:ppEnabledExtensionNames is provided as part of a layer, then both the layer and extension must: be enabled to enable that extension</usage>
                 <usage>The pname:queueFamilyIndex member of any given element of pname:pQueueCreateInfos must: be unique within pname:pQueueCreateInfos</usage>
             </validity>
         </type>
@@ -521,9 +518,6 @@
             <member optional="true"><type>uint32_t</type>               <name>enabledExtensionCount</name></member>
             <member len="enabledExtensionCount,null-terminated">const <type>char</type>* const*      <name>ppEnabledExtensionNames</name></member>        <!-- Extension names to be enabled -->
             <validity>
-                <usage>Any given element of pname:ppEnabledLayerNames must: be the name of a layer present on the system, exactly matching a string returned in the sname:VkLayerProperties structure by fname:vkEnumerateInstanceLayerProperties</usage>
-                <usage>Any given element of pname:ppEnabledExtensionNames must: be the name of an extension present on the system, exactly matching a string returned in the sname:VkExtensionProperties structure by fname:vkEnumerateInstanceExtensionProperties</usage>
-                <usage>If an extension listed in pname:ppEnabledExtensionNames is provided as part of a layer, then both the layer and extension must: be enabled to enable that extension</usage>
             </validity>
         </type>
         <type category="struct" name="VkQueueFamilyProperties" returnedonly="true">
@@ -540,7 +534,7 @@
         </type>
         <type category="struct" name="VkMemoryAllocateInfo">
             <member><type>VkStructureType</type>        <name>sType</name></member>                          <!-- Must be VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO -->
-            <member>const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure -->
+            <member validextensionstructs="VkDedicatedAllocationMemoryAllocateInfoNV">const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure -->
             <member><type>VkDeviceSize</type>           <name>allocationSize</name></member>                 <!-- Size of memory allocation -->
             <member><type>uint32_t</type>               <name>memoryTypeIndex</name></member>                <!-- Index of the of the memory type to allocate from -->
             <validity>
@@ -551,7 +545,7 @@
         <type category="struct" name="VkMemoryRequirements" returnedonly="true">
             <member><type>VkDeviceSize</type>           <name>size</name></member>                           <!-- Specified in bytes -->
             <member><type>VkDeviceSize</type>           <name>alignment</name></member>                      <!-- Specified in bytes -->
-            <member><type>uint32_t</type>               <name>memoryTypeBits</name></member>                 <!-- Bitfield of the allowed memory type indices into memoryTypes[] for this object -->
+            <member><type>uint32_t</type>               <name>memoryTypeBits</name></member>                 <!-- Bitmask of the allowed memory type indices into memoryTypes[] for this object -->
         </type>
         <type category="struct" name="VkSparseImageFormatProperties" returnedonly="true">
             <member optional="true"><type>VkImageAspectFlags</type>     <name>aspectMask</name></member>
@@ -610,8 +604,8 @@
             </validity>
         </type>
         <type category="struct" name="VkDescriptorImageInfo">
-            <member noautovalidity="true"><type>VkSampler</type>       <name>sampler</name></member>                        <!-- Sampler to write to the descriptor in case it's a SAMPLER or COMBINED_IMAGE_SAMPLER descriptor. Ignored otherwise. -->
-            <member noautovalidity="true"><type>VkImageView</type>     <name>imageView</name></member>                      <!-- Image view to write to the descriptor in case it's a SAMPLED_IMAGE, STORAGE_IMAGE, COMBINED_IMAGE_SAMPLER, or INPUT_ATTACHMENT descriptor. Ignored otherwise. -->
+            <member noautovalidity="true"><type>VkSampler</type>       <name>sampler</name></member>                        <!-- Sampler to write to the descriptor in case it is a SAMPLER or COMBINED_IMAGE_SAMPLER descriptor. Ignored otherwise. -->
+            <member noautovalidity="true"><type>VkImageView</type>     <name>imageView</name></member>                      <!-- Image view to write to the descriptor in case it is a SAMPLED_IMAGE, STORAGE_IMAGE, COMBINED_IMAGE_SAMPLER, or INPUT_ATTACHMENT descriptor. Ignored otherwise. -->
             <member noautovalidity="true"><type>VkImageLayout</type>   <name>imageLayout</name></member>                    <!-- Layout the image is expected to be in when accessed using this descriptor (only used if imageView is not VK_NULL_HANDLE). -->
         </type>
         <type category="struct" name="VkWriteDescriptorSet">
@@ -665,7 +659,7 @@
         </type>
         <type category="struct" name="VkBufferCreateInfo">
             <member><type>VkStructureType</type>        <name>sType</name></member>                          <!-- Must be VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO -->
-            <member>const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure. -->
+            <member validextensionstructs="VkDedicatedAllocationBufferCreateInfoNV">const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure. -->
             <member optional="true"><type>VkBufferCreateFlags</type>    <name>flags</name></member>                          <!-- Buffer creation flags -->
             <member><type>VkDeviceSize</type>           <name>size</name></member>                           <!-- Specified in bytes -->
             <member><type>VkBufferUsageFlags</type>     <name>usage</name></member>                          <!-- Buffer usage flags -->
@@ -772,7 +766,7 @@
             <member><type>VkImage</type>                <name>image</name></member>                          <!-- Image to sync -->
             <member><type>VkImageSubresourceRange</type> <name>subresourceRange</name></member>              <!-- Subresource range to sync -->
             <validity>
-                <usage>pname:oldLayout must: be ename:VK_IMAGE_LAYOUT_UNDEFINED, ename:VK_IMAGE_LAYOUT_PREINITIALIZED or the current layout of the image region affected by the barrier</usage>
+                <usage>pname:oldLayout must: be ename:VK_IMAGE_LAYOUT_UNDEFINED or the current layout of the image subresources affected by the barrier</usage>
                 <usage>pname:newLayout mustnot: be ename:VK_IMAGE_LAYOUT_UNDEFINED or ename:VK_IMAGE_LAYOUT_PREINITIALIZED</usage>
                 <usage>If pname:image was created with a sharing mode of ename:VK_SHARING_MODE_CONCURRENT, pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: both be ename:VK_QUEUE_FAMILY_IGNORED</usage>
                 <usage>If pname:image was created with a sharing mode of ename:VK_SHARING_MODE_EXCLUSIVE, pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: either both be ename:VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see &lt;&lt;devsandqueues-queueprops&gt;&gt;)</usage>
@@ -789,7 +783,7 @@
         </type>
         <type category="struct" name="VkImageCreateInfo">
             <member><type>VkStructureType</type>        <name>sType</name></member>                          <!-- Must be VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO -->
-            <member>const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure. -->
+            <member validextensionstructs="VkDedicatedAllocationImageCreateInfoNV">const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure. -->
             <member optional="true"><type>VkImageCreateFlags</type>     <name>flags</name></member>                          <!-- Image creation flags -->
             <member><type>VkImageType</type>            <name>imageType</name></member>
             <member><type>VkFormat</type>               <name>format</name></member>
@@ -820,16 +814,9 @@
                 <usage>pname:mipLevels must: be less than or equal to latexmath:[$\lfloor\log_2(\max(\mathit{extent.width}, \mathit{extent.height}, \mathit{extent.depth}))\rfloor + 1$]</usage>
                 <usage>If any of pname:extent.width, pname:extent.height or pname:extent.depth are greater than the equivalently named members of sname:VkPhysicalDeviceLimits::pname:maxImageDimension3D, pname:mipLevels must: be less than or equal to sname:VkImageFormatProperties::pname:maxMipLevels (as returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage and pname:flags equal to those in this structure)</usage>
                 <usage>pname:arrayLayers must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxImageArrayLayers, or sname:VkImageFormatProperties::pname:maxArrayLayers (as returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage and pname:flags equal to those in this structure) - whichever is higher</usage>
-                <usage>pname:samples must: be a bit value that is set in sname:VkPhysicalDeviceLimits::pname:sampleCounts returned by flink:vkGetPhysicalDeviceProperties, or sname:VkImageFormatProperties::pname:sampleCounts returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage and pname:flags equal to those in this structure</usage>
                 <usage>If pname:usage includes ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT or ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, pname:extent.width must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxFramebufferWidth</usage>
                 <usage>If pname:usage includes ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT or ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, pname:extent.height must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxFramebufferHeight</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, pname:samples must: be a bit value that is set in sname:VkPhysicalDeviceLimits::pname:framebufferColorSampleCounts</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, and pname:format includes a depth aspect, pname:samples must: be a bit value that is set in sname:VkPhysicalDeviceLimits::pname:framebufferDepthSampleCounts</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, and pname:format includes a stencil aspect, pname:samples must: be a bit value that is set in sname:VkPhysicalDeviceLimits::pname:framebufferStencilSampleCounts</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_SAMPLED_BIT, and pname:format includes a color aspect, pname:samples must: be a bit value that is set in sname:VkPhysicalDeviceLimits::pname:sampledImageColorSampleCounts</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_SAMPLED_BIT, and pname:format includes a depth aspect, pname:samples must: be a bit value that is set in sname:VkPhysicalDeviceLimits::pname:sampledImageDepthSampleCounts</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_SAMPLED_BIT, and pname:format is an integer format, pname:samples must: be a bit value that is set in sname:VkPhysicalDeviceLimits::pname:sampledImageIntegerSampleCounts</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_STORAGE_BIT, pname:samples must: be a bit value that is set in sname:VkPhysicalDeviceLimits::pname:storageImageSampleCounts</usage>
+                <usage>pname:samples must: be a bit value that is set in sname:VkImageFormatProperties::pname:sampleCounts returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage and pname:flags equal to those in this structure</usage>
                 <usage>If the &lt;&lt;features-features-textureCompressionETC2,ETC2 texture compression&gt;&gt; feature is not enabled, pname:format mustnot: be ename:VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, ename:VK_FORMAT_EAC_R11_UNORM_BLOCK, ename:VK_FORMAT_EAC_R11_SNORM_BLOCK, ename:VK_FORMAT_EAC_R11G11_UNORM_BLOCK, or ename:VK_FORMAT_EAC_R11G11_SNORM_BLOCK</usage>
                 <usage>If the &lt;&lt;features-features-textureCompressionASTC_LDR,ASTC LDR texture compression&gt;&gt; feature is not enabled, pname:format mustnot: be ename:VK_FORMAT_ASTC_4x4_UNORM_BLOCK, ename:VK_FORMAT_ASTC_4x4_SRGB_BLOCK, ename:VK_FORMAT_ASTC_5x4_UNORM_BLOCK, ename:VK_FORMAT_ASTC_5x4_SRGB_BLOCK, ename:VK_FORMAT_ASTC_5x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_5x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_6x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_6x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_6x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_6x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x8_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x8_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x8_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x8_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x10_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x10_SRGB_BLOCK, ename:VK_FORMAT_ASTC_12x10_UNORM_BLOCK, ename:VK_FORMAT_ASTC_12x10_SRGB_BLOCK, ename:VK_FORMAT_ASTC_12x12_UNORM_BLOCK, or ename:VK_FORMAT_ASTC_12x12_SRGB_BLOCK</usage>
                 <usage>If the &lt;&lt;features-features-textureCompressionBC,BC texture compression&gt;&gt; feature is not enabled, pname:format mustnot: be ename:VK_FORMAT_BC1_RGB_UNORM_BLOCK, ename:VK_FORMAT_BC1_RGB_SRGB_BLOCK, ename:VK_FORMAT_BC1_RGBA_UNORM_BLOCK, ename:VK_FORMAT_BC1_RGBA_SRGB_BLOCK, ename:VK_FORMAT_BC2_UNORM_BLOCK, ename:VK_FORMAT_BC2_SRGB_BLOCK, ename:VK_FORMAT_BC3_UNORM_BLOCK, ename:VK_FORMAT_BC3_SRGB_BLOCK, ename:VK_FORMAT_BC4_UNORM_BLOCK, ename:VK_FORMAT_BC4_SNORM_BLOCK, ename:VK_FORMAT_BC5_UNORM_BLOCK, ename:VK_FORMAT_BC5_SNORM_BLOCK, ename:VK_FORMAT_BC6H_UFLOAT_BLOCK, ename:VK_FORMAT_BC6H_SFLOAT_BLOCK, ename:VK_FORMAT_BC7_UNORM_BLOCK, or ename:VK_FORMAT_BC7_SRGB_BLOCK</usage>
@@ -900,8 +887,8 @@
             <member><type>VkDeviceSize</type>           <name>memoryOffset</name></member>                   <!-- Specified in bytes -->
             <member optional="true"><type>VkSparseMemoryBindFlags</type><name>flags</name></member>                          <!-- Reserved for future -->
             <validity>
-                <usage>If pname:memory is not sname:VK_NULL_HANDLE, pname:memory and pname:memoryOffset must: match the memory requirements of the resource, as described in section &lt;&lt;resources-association&gt;&gt;</usage>
-                <usage>If pname:memory is not sname:VK_NULL_HANDLE, pname:memory mustnot: have been created with a memory type that reports ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set</usage>
+                <usage>If pname:memory is not dlink:VK_NULL_HANDLE, pname:memory and pname:memoryOffset must: match the memory requirements of the resource, as described in section &lt;&lt;resources-association&gt;&gt;</usage>
+                <usage>If pname:memory is not dlink:VK_NULL_HANDLE, pname:memory mustnot: have been created with a memory type that reports ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set</usage>
                 <usage>pname:size must: be greater than `0`</usage>
                 <usage>pname:resourceOffset must: be less than the size of the resource</usage>
                 <usage>pname:size must: be less than or equal to the size of the resource minus pname:resourceOffset</usage>
@@ -1002,6 +989,7 @@
                 <usage>If either of the calling command's pname:srcImage or pname:dstImage parameters are of elink:VkImageType ename:VK_IMAGE_TYPE_3D, the pname:baseArrayLayer and pname:layerCount members of both pname:srcSubresource and pname:dstSubresource must: be `0` and `1`, respectively</usage>
                 <usage>The pname:aspectMask member of pname:srcSubresource must: specify aspects present in the calling command's pname:srcImage</usage>
                 <usage>The pname:aspectMask member of pname:dstSubresource must: specify aspects present in the calling command's pname:dstImage</usage>
+                <usage>The pname:layerCount member of pname:dstSubresource must: be equal to the pname:layerCount member of pname:srcSubresource</usage>
                 <usage>pname:srcOffset[0].x and pname:srcOffset[1].x must: both be greater than or equal to `0` and less than or equal to the source image subresource width</usage>
                 <usage>pname:srcOffset[0].y and pname:srcOffset[1].y must: both be greater than or equal to `0` and less than or equal to the source image subresource height</usage>
                 <usage>pname:srcOffset[0].z and pname:srcOffset[1].z must: both be greater than or equal to `0` and less than or equal to the source image subresource depth</usage>
@@ -1106,7 +1094,7 @@
         <type category="struct" name="VkDescriptorSetAllocateInfo">
             <member><type>VkStructureType</type>        <name>sType</name></member>                          <!-- Must be VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO -->
             <member>const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure -->
-            <member><type>VkDescriptorPool</type> <name>descriptorPool</name></member>
+            <member><type>VkDescriptorPool</type>       <name>descriptorPool</name></member>
             <member><type>uint32_t</type>               <name>descriptorSetCount</name></member>
             <member len="descriptorSetCount">const <type>VkDescriptorSetLayout</type>* <name>pSetLayouts</name></member>
             <validity>
@@ -1118,6 +1106,9 @@
             <member><type>uint32_t</type>               <name>constantID</name></member>                     <!-- The SpecConstant ID specified in the BIL -->
             <member><type>uint32_t</type>               <name>offset</name></member>                         <!-- Offset of the value in the data block -->
             <member><type>size_t</type>                 <name>size</name></member>                           <!-- Size in bytes of the SpecConstant -->
+            <validity>
+                <usage>For a pname:constantID specialization constant declared in a shader, pname:size must: match the byte size of the pname:constantID. If the specialization constant is of type boolean, pname:size must: be the byte size of VkBool32</usage>
+            </validity>
         </type>
         <type category="struct" name="VkSpecializationInfo">
             <member optional="true"><type>uint32_t</type>               <name>mapEntryCount</name></member>                  <!-- Number of entries in the map -->
@@ -1165,11 +1156,11 @@
             <member noautovalidity="true" optional="true"><type>VkPipeline</type>      <name>basePipelineHandle</name></member>             <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of -->
             <member><type>int32_t</type>                <name>basePipelineIndex</name></member>              <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of -->
             <validity>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, pname:basePipelineHandle must: be sname:VK_NULL_HANDLE</usage>
+                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, pname:basePipelineHandle must: be dlink:VK_NULL_HANDLE</usage>
                 <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, it must: be a valid index into the calling command's pname:pCreateInfos parameter</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not sname:VK_NULL_HANDLE, pname:basePipelineIndex must: be `-1`</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not sname:VK_NULL_HANDLE, pname:basePipelineHandle must: be a valid sname:VkPipeline handle</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not sname:VK_NULL_HANDLE, it must: be a valid handle to a compute sname:VkPipeline</usage>
+                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, pname:basePipelineIndex must: be `-1`</usage>
+                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, pname:basePipelineHandle must: be a valid sname:VkPipeline handle</usage>
+                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, it must: be a valid handle to a compute sname:VkPipeline</usage>
                 <usage>The pname:stage member of pname:stage must: be ename:VK_SHADER_STAGE_COMPUTE_BIT</usage>
                 <usage>The shader code for the entry point identified by pname:stage and the rest of the state identified by this structure must: adhere to the pipeline linking rules described in the &lt;&lt;interfaces,Shader Interfaces&gt;&gt; chapter</usage>
                 <usage>pname:layout must: be &lt;&lt;descriptorsets-pipelinelayout-consistency,consistent&gt;&gt; with all shaders specified in pname:pStages</usage>
@@ -1370,23 +1361,24 @@
             <member noautovalidity="true" optional="true"><type>VkPipeline</type>      <name>basePipelineHandle</name></member>             <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of -->
             <member><type>int32_t</type>                <name>basePipelineIndex</name></member>              <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of -->
             <validity>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, pname:basePipelineHandle must: be sname:VK_NULL_HANDLE</usage>
+                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, pname:basePipelineHandle must: be dlink:VK_NULL_HANDLE</usage>
                 <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, it must: be a valid index into the calling command's pname:pCreateInfos parameter</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not sname:VK_NULL_HANDLE, pname:basePipelineIndex must: be `-1`</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not sname:VK_NULL_HANDLE, pname:basePipelineHandle must: be a valid sname:VkPipeline handle</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not sname:VK_NULL_HANDLE, it must: be a valid handle to a graphics sname:VkPipeline</usage>
+                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, pname:basePipelineIndex must: be `-1`</usage>
+                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, pname:basePipelineHandle must: be a valid sname:VkPipeline handle</usage>
+                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, it must: be a valid handle to a graphics sname:VkPipeline</usage>
                 <usage>The pname:stage member of each element of pname:pStages must: be unique</usage>
                 <usage>The pname:stage member of one element of pname:pStages must: be ename:VK_SHADER_STAGE_VERTEX_BIT</usage>
                 <usage>The pname:stage member of any given element of pname:pStages mustnot: be ename:VK_SHADER_STAGE_COMPUTE_BIT</usage>
                 <usage>If pname:pStages includes a tessellation control shader stage, it must: include a tessellation evaluation shader stage</usage>
                 <usage>If pname:pStages includes a tessellation evaluation shader stage, it must: include a tessellation control shader stage</usage>
                 <usage>If pname:pStages includes a tessellation control shader stage and a tessellation evaluation shader stage, pname:pTessellationState mustnot: be `NULL`</usage>
-                <usage>If pname:pStages includes both a tessellation control shader stage and a tessellation evaluation shader stage, the shader code of at least one must: contain an code:OpExecutionMode instruction that specifies the type of subdivision in the pipeline</usage>
-                <usage>If pname:pStages includes both a tessellation control shader stage and a tessellation evaluation shader stage, and the shader code of both contain an code:OpExecutionMode instruction that specifies the type of subdivision in the pipeline, they must: both specify the same subdivision mode</usage>
-                <usage>If pname:pStages includes both a tessellation control shader stage and a tessellation evaluation shader stage, the shader code of at least one must: contain an code:OpExecutionMode instruction that specifies the output patch size in the pipeline</usage>
-                <usage>If pname:pStages includes both a tessellation control shader stage and a tessellation evaluation shader stage, and the shader code of both contain an code:OpExecutionMode instruction that specifies the out patch size in the pipeline, they must: both specify the same patch size</usage>
+                <usage>If pname:pStages includes tessellation shader stages, the shader code of at least one stage must: contain an code:OpExecutionMode instruction that specifies the type of subdivision in the pipeline</usage>
+                <usage>If pname:pStages includes tessellation shader stages, and the shader code of both stages contain an code:OpExecutionMode instruction that specifies the type of subdivision in the pipeline, they must: both specify the same subdivision mode</usage>
+                <usage>If pname:pStages includes tessellation shader stages, the shader code of at least one stage must: contain an code:OpExecutionMode instruction that specifies the output patch size in the pipeline</usage>
+                <usage>If pname:pStages includes tessellation shader stages, and the shader code of both contain an code:OpExecutionMode instruction that specifies the out patch size in the pipeline, they must: both specify the same patch size</usage>
                 <usage>If pname:pStages includes tessellation shader stages, the pname:topology member of pname:pInputAssembly must: be ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST</usage>
-                <usage>If pname:pStages includes a geometry shader stage, and doesn't include any tessellation shader stages, its shader code must: contain an code:OpExecutionMode instruction that specifies an input primitive type that is &lt;&lt;shaders-geometry-execution, compatible&gt;&gt; with the primitive topology specified in pname:pInputAssembly</usage>
+                <usage>If the pname:topology member of pname:pInputAssembly is ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pname:pStages must: include tessellation shader stages</usage>
+                <usage>If pname:pStages includes a geometry shader stage, and does not include any tessellation shader stages, its shader code must: contain an code:OpExecutionMode instruction that specifies an input primitive type that is &lt;&lt;shaders-geometry-execution, compatible&gt;&gt; with the primitive topology specified in pname:pInputAssembly</usage>
                 <usage>If pname:pStages includes a geometry shader stage, and also includes tessellation shader stages, its shader code must: contain an code:OpExecutionMode instruction that specifies an input primitive type that is &lt;&lt;shaders-geometry-execution, compatible&gt;&gt; with the primitive topology that is output by the tessellation stages</usage>
                 <usage>If pname:pStages includes a fragment shader stage and a geometry shader stage, and the fragment shader code reads from an input variable that is decorated with code:PrimitiveID, then the geometry shader code must: write to a matching output variable, decorated with code:PrimitiveID, in all execution paths</usage>
                 <usage>If pname:pStages includes a fragment shader stage, its shader code mustnot: read from any input attachment that is defined as ename:VK_ATTACHMENT_UNUSED in pname:subpass</usage>
@@ -1486,7 +1478,7 @@
         <type category="struct" name="VkCommandPoolCreateInfo">
             <member><type>VkStructureType</type>        <name>sType</name></member>                          <!-- Must be VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO -->
             <member>const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure -->
-            <member optional="true"><type>VkCommandPoolCreateFlags</type>   <name>flags</name></member>                          <!-- Command pool creation flags -->
+            <member optional="true"><type>VkCommandPoolCreateFlags</type>   <name>flags</name></member>      <!-- Command pool creation flags -->
             <member><type>uint32_t</type>               <name>queueFamilyIndex</name></member>
             <validity>
                 <usage>pname:queueFamilyIndex must: be the index of a queue family available in the calling command's pname:device parameter</usage>
@@ -1495,9 +1487,12 @@
          <type category="struct" name="VkCommandBufferAllocateInfo">
             <member><type>VkStructureType</type>        <name>sType</name></member>                          <!-- Must be VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO -->
             <member>const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure -->
-            <member><type>VkCommandPool</type>  <name>commandPool</name></member>
-            <member><type>VkCommandBufferLevel</type>       <name>level</name></member>
+            <member><type>VkCommandPool</type>          <name>commandPool</name></member>
+            <member><type>VkCommandBufferLevel</type>   <name>level</name></member>
             <member><type>uint32_t</type>               <name>commandBufferCount</name></member>
+            <validity>
+                <usage>pname:commandBufferCount must: be greater than `0`</usage>
+            </validity>
         </type>
         <type category="struct" name="VkCommandBufferInheritanceInfo">
             <member><type>VkStructureType</type>        <name>sType</name></member>                          <!-- Must be VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO -->
@@ -1522,7 +1517,7 @@
             <validity>
                 <usage>If pname:flags contains ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the pname:renderPass member of pname:pInheritanceInfo must: be a valid sname:VkRenderPass</usage>
                 <usage>If pname:flags contains ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the pname:subpass member of pname:pInheritanceInfo must: be a valid subpass index within the pname:renderPass member of pname:pInheritanceInfo</usage>
-                <usage>If pname:flags contains ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the pname:framebuffer member of pname:pInheritanceInfo must: be either sname:VK_NULL_HANDLE, or a valid sname:VkFramebuffer that is compatible with the pname:renderPass member of pname:pInheritanceInfo</usage>
+                <usage>If pname:flags contains ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the pname:framebuffer member of pname:pInheritanceInfo must: be either dlink:VK_NULL_HANDLE, or a valid sname:VkFramebuffer that is compatible with the pname:renderPass member of pname:pInheritanceInfo</usage>
             </validity>
         </type>
         <type category="struct" name="VkRenderPassBeginInfo">
@@ -1935,7 +1930,7 @@
                 <usage>Any given element of pname:pCommandBuffers mustnot: contain commands that execute a secondary command buffer, if that secondary command buffer has been recorded in another primary command buffer after it was recorded into this sname:VkCommandBuffer</usage>
                 <usage>Any given element of pname:pCommandBuffers must: have been created on a sname:VkCommandPool that was created for the same queue family that the calling command's pname:queue belongs to</usage>
                 <usage>Any given element of pname:pCommandBuffers mustnot: have been created with ename:VK_COMMAND_BUFFER_LEVEL_SECONDARY</usage>
-                <usage>Any given element of sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal of that sname:VkSemaphore that won't be consumed by any other wait on that semaphore</usage>
+                <usage>Any given element of sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal of that sname:VkSemaphore that will not be consumed by any other wait on that semaphore</usage>
                 <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, any given element of pname:pWaitDstStageMask mustnot: contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
                 <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, any given element of pname:pWaitDstStageMask mustnot: contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
             </validity>
@@ -2120,7 +2115,7 @@
             <member optional="true" len="swapchainCount"><type>VkResult</type>* <name>pResults</name></member>   <!-- Optional (i.e. if non-NULL) VkResult for each swapchain -->
             <validity>
                 <usage>Any given element of pname:pImageIndices must: be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pname:pSwapchains array</usage>
-                <usage>Any given element of sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal of that sname:VkSemaphore that won't be consumed by any other wait on that semaphore</usage>
+                <usage>Any given element of sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal of that sname:VkSemaphore that will not be consumed by any other wait on that semaphore</usage>
             </validity>
         </type>
         <type category="struct" name="VkDebugReportCallbackCreateInfoEXT">
@@ -2157,6 +2152,35 @@
             <member len="null-terminated">const <type>char</type>* <name>pMarkerName</name></member>             <!-- Name of the debug marker -->
             <member optional="true"><type>float</type>            <name>color</name>[4]</member>                 <!-- Optional color for debug marker -->
         </type>
+        <type category="struct" name="VkDedicatedAllocationImageCreateInfoNV">
+            <member><type>VkStructureType</type>                  <name>sType</name></member>                    <!-- Must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV -->
+            <member>const <type>void</type>*                      <name>pNext</name></member>                    <!-- Pointer to next structure -->
+            <member><type>VkBool32</type>                         <name>dedicatedAllocation</name></member>      <!-- Whether this image uses a dedicated allocation -->
+            <validity>
+                <usage>If pname:dedicatedAllocation is ename:VK_TRUE, sname:VkImageCreateInfo::pname:flags mustnot: include ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT, ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or ename:VK_IMAGE_CREATE_SPARSE_ALIASED_BIT</usage>
+            </validity>
+        </type>
+        <type category="struct" name="VkDedicatedAllocationBufferCreateInfoNV">
+            <member><type>VkStructureType</type>                  <name>sType</name></member>                    <!-- Must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV -->
+            <member>const <type>void</type>*                      <name>pNext</name></member>                    <!-- Pointer to next structure -->
+            <member><type>VkBool32</type>                         <name>dedicatedAllocation</name></member>      <!-- Whether this buffer uses a dedicated allocation -->
+            <validity>
+                <usage>If pname:dedicatedAllocation is ename:VK_TRUE, sname:VkBufferCreateInfo::pname:flags mustnot: include ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT, ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, or ename:VK_BUFFER_CREATE_SPARSE_ALIASED_BIT</usage>
+            </validity>
+        </type>
+        <type category="struct" name="VkDedicatedAllocationMemoryAllocateInfoNV">
+            <member><type>VkStructureType</type>                  <name>sType</name></member>                    <!-- Must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV -->
+            <member>const <type>void</type>*                      <name>pNext</name></member>                    <!-- Pointer to next structure -->
+            <member optional="true"><type>VkImage</type>          <name>image</name></member>                    <!-- Image that this allocation will be bound to -->
+            <member optional="true"><type>VkBuffer</type>         <name>buffer</name></member>                   <!-- Buffer that this allocation will be bound to -->
+            <validity>
+                <usage>At least one of pname:image and pname:buffer must: be sname:VK_NULL_HANDLE</usage>
+                <usage>If pname:image is not sname:VK_NULL_HANDLE, the image must: have been created with sname:VkDedicatedAllocationImageCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE</usage>
+                <usage>If pname:buffer is not sname:VK_NULL_HANDLE, the buffer must: have been created with sname:VkDedicatedAllocationBufferCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE</usage>
+                <usage>If pname:image is not sname:VK_NULL_HANDLE, sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the sname:VkMemoryRequirements::pname:size of the image</usage>
+                <usage>If pname:buffer is not sname:VK_NULL_HANDLE, sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the sname:VkMemoryRequirements::pname:size of the buffer</usage>
+            </validity>
+        </type>
     </types>
 
     <!-- SECTION: Vulkan enumerant (token) definitions. -->
@@ -2781,13 +2805,13 @@
     <enums name="VkFormatFeatureFlagBits" type="bitmask">
         <enum bitpos="0"    name="VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT"               comment="Format can be used for sampled images (SAMPLED_IMAGE and COMBINED_IMAGE_SAMPLER descriptor types)"/>
         <enum bitpos="1"    name="VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT"               comment="Format can be used for storage images (STORAGE_IMAGE descriptor type)"/>
-        <enum bitpos="2"    name="VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT"        comment="Format supports atomic operations in case it's used for storage images"/>
+        <enum bitpos="2"    name="VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT"        comment="Format supports atomic operations in case it is used for storage images"/>
         <enum bitpos="3"    name="VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT"        comment="Format can be used for uniform texel buffers (TBOs)"/>
         <enum bitpos="4"    name="VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT"        comment="Format can be used for storage texel buffers (IBOs)"/>
-        <enum bitpos="5"    name="VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" comment="Format supports atomic operations in case it's used for storage texel buffers"/>
+        <enum bitpos="5"    name="VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" comment="Format supports atomic operations in case it is used for storage texel buffers"/>
         <enum bitpos="6"    name="VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT"               comment="Format can be used for vertex buffers (VBOs)"/>
         <enum bitpos="7"    name="VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT"            comment="Format can be used for color attachment images"/>
-        <enum bitpos="8"    name="VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT"      comment="Format supports blending in case it's used for color attachment images"/>
+        <enum bitpos="8"    name="VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT"      comment="Format supports blending in case it is used for color attachment images"/>
         <enum bitpos="9"    name="VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT"    comment="Format can be used for depth/stencil attachment images"/>
         <enum bitpos="10"   name="VK_FORMAT_FEATURE_BLIT_SRC_BIT"                    comment="Format can be used as the source image of blits with vkCmdBlitImage"/>
         <enum bitpos="11"   name="VK_FORMAT_FEATURE_BLIT_DST_BIT"                    comment="Format can be used as the destination image of blits with vkCmdBlitImage"/>
@@ -2800,7 +2824,7 @@
         <enum bitpos="0"    name="VK_QUERY_RESULT_64_BIT"                            comment="Results of the queries are written to the destination buffer as 64-bit values"/>
         <enum bitpos="1"    name="VK_QUERY_RESULT_WAIT_BIT"                          comment="Results of the queries are waited on before proceeding with the result copy"/>
         <enum bitpos="2"    name="VK_QUERY_RESULT_WITH_AVAILABILITY_BIT"             comment="Besides the results of the query, the availability of the results is also written"/>
-        <enum bitpos="3"    name="VK_QUERY_RESULT_PARTIAL_BIT"                       comment="Copy the partial results of the query even if the final results aren't available"/>
+        <enum bitpos="3"    name="VK_QUERY_RESULT_PARTIAL_BIT"                       comment="Copy the partial results of the query even if the final results are not available"/>
     </enums>
     <enums name="VkCommandBufferUsageFlagBits" type="bitmask">
         <enum bitpos="0"    name="VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT"/>
@@ -2995,7 +3019,6 @@
             <param><type>VkDevice</type> <name>device</name></param>
             <param len="null-terminated">const <type>char</type>* <name>pName</name></param>
             <validity>
-                <usage>pname:pName must: be the name of a supported command that has a first parameter of type sname:VkDevice, sname:VkQueue or sname:VkCommandBuffer, either in the core API or an enabled extension</usage>
             </validity>
         </command>
         <command>
@@ -3003,8 +3026,8 @@
             <param optional="true"><type>VkInstance</type> <name>instance</name></param>
             <param len="null-terminated">const <type>char</type>* <name>pName</name></param>
             <validity>
-                <usage>If pname:instance is `NULL`, pname:pName must: be one of: fname:vkEnumerateInstanceExtensionProperties, fname:vkEnumerateInstanceLayerProperties or fname:vkCreateInstance</usage>
-                <usage>If pname:instance is not `NULL`, pname:pName must: be the name of a core command or a command from an enabled extension, other than: fname:vkEnumerateInstanceExtensionProperties, fname:vkEnumerateInstanceLayerProperties or fname:vkCreateInstance</usage>
+                <usage>If pname:instance is `NULL`, pname:pName must: be "vkEnumerateInstanceExtensionProperties", "vkEnumerateInstanceLayerProperties", or "vkCreateInstance"</usage>
+                <usage>If pname:instance is not `NULL`, pname:pName mustnot: be "vkEnumerateInstanceExtensionProperties", "vkEnumerateInstanceLayerProperties", or "vkCreateInstance"</usage>
             </validity>
         </command>
         <command>
@@ -3044,7 +3067,7 @@
             <param optional="true"><type>VkImageCreateFlags</type> <name>flags</name></param>
             <param><type>VkImageFormatProperties</type>* <name>pImageFormatProperties</name></param>
         </command>
-        <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED,VK_ERROR_LAYER_NOT_PRESENT,VK_ERROR_EXTENSION_NOT_PRESENT,VK_ERROR_FEATURE_NOT_PRESENT,VK_ERROR_TOO_MANY_OBJECTS,VK_ERROR_DEVICE_LOST">
+        <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED,VK_ERROR_EXTENSION_NOT_PRESENT,VK_ERROR_FEATURE_NOT_PRESENT,VK_ERROR_TOO_MANY_OBJECTS,VK_ERROR_DEVICE_LOST">
             <proto><type>VkResult</type> <name>vkCreateDevice</name></proto>
             <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
             <param>const <type>VkDeviceCreateInfo</type>* <name>pCreateInfo</name></param>
@@ -3109,8 +3132,8 @@
             <param len="submitCount" externsync="pSubmits[].pWaitSemaphores[],pSubmits[].pSignalSemaphores[]">const <type>VkSubmitInfo</type>* <name>pSubmits</name></param>
             <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
             <validity>
-                <usage>If pname:fence is not sname:VK_NULL_HANDLE, pname:fence must: be unsignaled</usage>
-                <usage>If pname:fence is not sname:VK_NULL_HANDLE, pname:fence mustnot: be associated with any other queue command that has not yet completed execution on that queue</usage>
+                <usage>If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: be unsignaled</usage>
+                <usage>If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence mustnot: be associated with any other queue command that has not yet completed execution on that queue</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
@@ -3208,8 +3231,8 @@
                 <usage>If pname:buffer was created with the ename:VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, pname:memoryOffset must: be a multiple of sname:VkPhysicalDeviceLimits::pname:minUniformBufferOffsetAlignment</usage>
                 <usage>If pname:buffer was created with the ename:VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, pname:memoryOffset must: be a multiple of sname:VkPhysicalDeviceLimits::pname:minStorageBufferOffsetAlignment</usage>
                 <usage>pname:memory must: have been allocated using one of the memory types allowed in the pname:memoryTypeBits member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetBufferMemoryRequirements with pname:buffer</usage>
-                <usage>The size of pname:buffer must: be less than or equal to the size of pname:memory minus pname:memoryOffset</usage>
                 <usage>pname:memoryOffset must: be an integer multiple of the pname:alignment member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetBufferMemoryRequirements with pname:buffer</usage>
+                <usage>The pname:size member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetBufferMemoryRequirements with pname:buffer must: be less than or equal to the size of pname:memory minus pname:memoryOffset</usage>
             </validity>
         </command>
         <command>
@@ -3251,14 +3274,10 @@
             <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
             <param optional="true" len="pPropertyCount"><type>VkSparseImageFormatProperties</type>* <name>pProperties</name></param>
             <validity>
-                <usage>If pname:format is an integer format, samples must: be one of the bit flags specified in sname:VkPhysicalDeviceLimits::pname:sampledImageIntegerSampleCounts</usage>
-                <usage>If pname:format is a non-integer color format, samples must: be one of the bit flags specified in sname:VkPhysicalDeviceLimits::pname:sampledImageColorSampleCounts</usage>
-                <usage>If pname:format is a depth format, samples must: be one of the bit flags specified in sname:VkPhysicalDeviceLimits::pname:sampledImageDepthSampleCounts</usage>
-                <usage>If pname:format is a stencil format, samples must: be one of the bit flags specified in sname:VkPhysicalDeviceLimits::pname:sampledImageStencilSampleCounts</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_STORAGE_BIT, samples must: be one of the bit flags specified in sname:VkPhysicalDeviceLimits::pname:storageImageSampleCounts</usage>
+                <usage>pname:samples must: be a bit value that is set in sname:VkImageFormatProperties::pname:sampleCounts returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, and pname:usage equal to those in this command and pname:flags equal to the value that is set in sname::VkImageCreateInfo::pname::flags when the image is created</usage>
             </validity>
         </command>
-        <command queues="sparse_binding" successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+        <command queues="sparse_binding" successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
             <proto><type>VkResult</type> <name>vkQueueBindSparse</name></proto>
             <param externsync="true"><type>VkQueue</type> <name>queue</name></param>
             <param optional="true"><type>uint32_t</type> <name>bindInfoCount</name></param>
@@ -3523,7 +3542,7 @@
                 <usage>If no sname:VkAllocationCallbacks were provided when pname:pipelineCache was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
-        <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+        <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
             <proto><type>VkResult</type> <name>vkGetPipelineCacheData</name></proto>
             <param><type>VkDevice</type> <name>device</name></param>
             <param><type>VkPipelineCache</type> <name>pipelineCache</name></param>
@@ -3671,7 +3690,8 @@
             <param noautovalidity="true" externsync="true" len="descriptorSetCount">const <type>VkDescriptorSet</type>* <name>pDescriptorSets</name></param>
             <validity>
                 <usage>All submitted commands that refer to any element of pname:pDescriptorSets must: have completed execution</usage>
-                <usage>pname:pDescriptorSets must: be a pointer to an array of pname:descriptorSetCount sname:VkDescriptorSet handles, each element of which must: either be a valid handle or sname:VK_NULL_HANDLE</usage>
+                <usage>pname:pDescriptorSets must: be a pointer to an array of pname:descriptorSetCount sname:VkDescriptorSet handles, each element of which must: either be a valid handle or dlink:VK_NULL_HANDLE</usage>
+                <usage>Each valid handle in pname:pDescriptorSets must: have been allocated from pname:descriptorPool</usage>
                 <usage>pname:descriptorPool must: have been created with the ename:VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT flag</usage>
             </validity>
         </command>
@@ -3766,7 +3786,7 @@
             <param noautovalidity="true" externsync="true" len="commandBufferCount">const <type>VkCommandBuffer</type>* <name>pCommandBuffers</name></param>
             <validity>
                 <usage>All elements of pname:pCommandBuffers mustnot: be pending execution</usage>
-                <usage>pname:pCommandBuffers must: be a pointer to an array of pname:commandBufferCount sname:VkCommandBuffer handles, each element of which must: either be a valid handle or sname:VK_NULL_HANDLE</usage>
+                <usage>pname:pCommandBuffers must: be a pointer to an array of pname:commandBufferCount sname:VkCommandBuffer handles, each element of which must: either be a valid handle or dlink:VK_NULL_HANDLE</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3787,7 +3807,7 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <validity>
                 <usage>pname:commandBuffer must: be in the recording state</usage>
-                <usage>fname:vkEndCommandBuffer mustnot: be called inside a render pass instance</usage>
+                <usage>If pname:commandBuffer is a primary command buffer, there mustnot: be an active render pass instance</usage>
                 <usage>All queries made &lt;&lt;queries-operation-active,active&gt;&gt; during the recording of pname:commandBuffer must: have been made inactive</usage>
             </validity>
         </command>
@@ -3820,6 +3840,7 @@
             <param><type>uint32_t</type> <name>viewportCount</name></param>
             <param len="viewportCount">const <type>VkViewport</type>* <name>pViewports</name></param>
             <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled</usage>
                 <usage>pname:firstViewport must: be less than sname:VkPhysicalDeviceLimits::pname:maxViewports</usage>
                 <usage>The sum of pname:firstViewport and pname:viewportCount must: be between `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive</usage>
             </validity>
@@ -3831,6 +3852,7 @@
             <param><type>uint32_t</type> <name>scissorCount</name></param>
             <param len="scissorCount">const <type>VkRect2D</type>* <name>pScissors</name></param>
             <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_SCISSOR dynamic state enabled</usage>
                 <usage>pname:firstScissor must: be less than sname:VkPhysicalDeviceLimits::pname:maxViewports</usage>
                 <usage>The sum of pname:firstScissor and pname:scissorCount must: be between `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive</usage>
                 <usage>The pname:x and pname:y members of pname:offset must: be greater than or equal to `0`</usage>
@@ -3843,6 +3865,7 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param><type>float</type> <name>lineWidth</name></param>
             <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled</usage>
                 <usage>If the &lt;&lt;features-features-wideLines,wide lines&gt;&gt; feature is not enabled, pname:lineWidth must: be `1.0`</usage>
             </validity>
         </command>
@@ -3853,6 +3876,7 @@
             <param><type>float</type> <name>depthBiasClamp</name></param>
             <param><type>float</type> <name>depthBiasSlopeFactor</name></param>
             <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled</usage>
                 <usage>If the &lt;&lt;features-features-depthBiasClamp,depth bias clamping&gt;&gt; feature is not enabled, pname:depthBiasClamp must: be code:0.0</usage>
             </validity>
         </command>
@@ -3860,6 +3884,9 @@
             <proto><type>void</type> <name>vkCmdSetBlendConstants</name></proto>
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param>const <type>float</type> <name>blendConstants</name>[4]</param>
+            <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled</usage>
+            </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
             <proto><type>void</type> <name>vkCmdSetDepthBounds</name></proto>
@@ -3867,6 +3894,7 @@
             <param><type>float</type> <name>minDepthBounds</name></param>
             <param><type>float</type> <name>maxDepthBounds</name></param>
             <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state enabled</usage>
                 <usage>pname:minDepthBounds must: be between `0.0` and `1.0`, inclusive</usage>
                 <usage>pname:maxDepthBounds must: be between `0.0` and `1.0`, inclusive</usage>
             </validity>
@@ -3876,18 +3904,27 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
             <param><type>uint32_t</type> <name>compareMask</name></param>
+            <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled</usage>
+            </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
             <proto><type>void</type> <name>vkCmdSetStencilWriteMask</name></proto>
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
             <param><type>uint32_t</type> <name>writeMask</name></param>
+            <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled</usage>
+            </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
             <proto><type>void</type> <name>vkCmdSetStencilReference</name></proto>
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
             <param><type>uint32_t</type> <name>reference</name></param>
+            <validity>
+                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled</usage>
+            </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
             <proto><type>void</type> <name>vkCmdBindDescriptorSets</name></proto>
@@ -3914,7 +3951,7 @@
             <param><type>VkIndexType</type> <name>indexType</name></param>
             <validity>
                 <usage>pname:offset must: be less than the size of pname:buffer</usage>
-                <usage>The sum of pname:offset, and the address of the range of sname:VkDeviceMemory object that's backing pname:buffer, must: be a multiple of the type indicated by pname:indexType</usage>
+                <usage>The sum of pname:offset and the address of the range of sname:VkDeviceMemory object that is backing pname:buffer, must: be a multiple of the type indicated by pname:indexType</usage>
                 <usage>pname:buffer must: have been created with the ename:VK_BUFFER_USAGE_INDEX_BUFFER_BIT flag</usage>
             </validity>
         </command>
@@ -4139,7 +4176,7 @@
             <validity>
                 <usage>The source region specified by a given element of pname:pRegions must: be a region that is contained within pname:srcImage</usage>
                 <usage>The destination region specified by a given element of pname:pRegions must: be a region that is contained within pname:dstImage</usage>
-                <usage>The union of all source regions, and the union of all destination regions, specified by the elements of pname:pRegions, mustnot: overlap in memory</usage>
+                <usage>The union of all destination regions, specified by the elements of pname:pRegions, mustnot: overlap in memory with any texel that may: be sampled during the blit operation</usage>
                 <usage>pname:srcImage must: use a format that supports ename:VK_FORMAT_FEATURE_BLIT_SRC_BIT, which is indicated by sname:VkFormatProperties::pname:linearTilingFeatures (for linear tiled images) or sname:VkFormatProperties::pname:optimalTilingFeatures (for optimally tiled images) - as returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
                 <usage>pname:srcImage must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag</usage>
                 <usage>pname:srcImageLayout must: specify the layout of the image subresources of pname:srcImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
@@ -4153,6 +4190,8 @@
                 <usage>If either of pname:srcImage or pname:dstImage was created with an unsigned integer elink:VkFormat, the other must: also have been created with an unsigned integer elink:VkFormat</usage>
                 <usage>If either of pname:srcImage or pname:dstImage was created with a depth/stencil format, the other must: have exactly the same format</usage>
                 <usage>If pname:srcImage was created with a depth/stencil format, pname:filter must: be ename:VK_FILTER_NEAREST</usage>
+                <usage>pname:srcImage must: have been created with a pname:samples value of ename:VK_SAMPLE_COUNT_1_BIT</usage>
+                <usage>pname:dstImage must: have been created with a pname:samples value of ename:VK_SAMPLE_COUNT_1_BIT</usage>
                 <usage>If pname:filter is ename:VK_FILTER_LINEAR, pname:srcImage must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
@@ -4200,9 +4239,8 @@
             <param><type>VkBuffer</type> <name>dstBuffer</name></param>
             <param><type>VkDeviceSize</type> <name>dstOffset</name></param>
             <param><type>VkDeviceSize</type> <name>dataSize</name></param>
-            <param len="latexmath:[$dataSize \over 4$]">const <type>uint32_t</type>* <name>pData</name></param>
+            <param len="dataSize">const <type>void</type>* <name>pData</name></param>
             <validity>
-                <usage>pname:dataSize must: be greater than `0`</usage>
                 <usage>pname:dstOffset must: be less than the size of pname:dstBuffer</usage>
                 <usage>pname:dataSize must: be less than or equal to the size of pname:dstBuffer minus pname:dstOffset</usage>
                 <usage>pname:dstBuffer must: have been created with ename:VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag</usage>
@@ -4451,11 +4489,12 @@
             <param>const <type>VkRenderPassBeginInfo</type>* <name>pRenderPassBegin</name></param>
             <param><type>VkSubpassContents</type> <name>contents</name></param>
             <validity>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then the corresponding attachment image of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set</usage>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then the corresponding attachment image of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set</usage>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then the corresponding attachment image of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_SAMPLED_BIT or ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set</usage>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_BIT then the corresponding attachment image of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT set</usage>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_TRANSFER_DST_BIT then the corresponding attachment image of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT set</usage>
+                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set</usage>
+                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set</usage>
+                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_SAMPLED_BIT or ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set</usage>
+                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT set</usage>
+                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT set</usage>
+                <usage>If any of the pname:initialLayout members of the sname:VkAttachmentDescription structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is not ename:VK_IMAGE_LAYOUT_UNDEFINED, then each such pname:initialLayout must: be equal to the current layout of the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin.</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary">
@@ -4463,14 +4502,14 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param><type>VkSubpassContents</type> <name>contents</name></param>
             <validity>
-              <usage>The current subpass index must: be less than the number of subpasses in the render pass minus one</usage>
+                <usage>The current subpass index must: be less than the number of subpasses in the render pass minus one</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary">
             <proto><type>void</type> <name>vkCmdEndRenderPass</name></proto>
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <validity>
-              <usage>The current subpass index must: be equal to the number of subpasses in the render pass minus one</usage>
+                <usage>The current subpass index must: be equal to the number of subpasses in the render pass minus one</usage>
             </validity>
         </command>
         <command queues="transfer,graphics,compute" renderpass="both" cmdbufferlevel="primary">
@@ -4486,12 +4525,12 @@
                 <usage>Any given element of pname:pCommandBuffers must: be in the executable state</usage>
                 <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, that render pass instance must: have been begun with the pname:contents parameter of fname:vkCmdBeginRenderPass set to ename:VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS</usage>
                 <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, any given element of pname:pCommandBuffers must: have been recorded with the ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</usage>
-                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, any given element of pname:pCommandBuffers must: have been recorded with the pname:subpass member of the pname:inheritanceInfo structure set to the index of the subpass which the given command buffer will be executed in</usage>
+                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, any given element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferInheritanceInfo::pname:subpass set to the index of the subpass which the given command buffer will be executed in</usage>
                 <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, any given element of pname:pCommandBuffers must: have been recorded with a render pass that is compatible with the current render pass - see &lt;&lt;renderpass-compatibility&gt;&gt;</usage>
-                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, and any given element of pname:pCommandBuffers was recorded with the pname:framebuffer member of the sname:VkCommandBufferInheritanceInfo structure not equal to sname:VK_NULL_HANDLE, that sname:VkFramebuffer must: be compatible with the sname:VkFramebuffer used in the current render pass instance</usage>
+                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, and any given element of pname:pCommandBuffers was recorded with sname:VkCommandBufferInheritanceInfo::pname:framebuffer not equal to dlink:VK_NULL_HANDLE, that sname:VkFramebuffer must: match the sname:VkFramebuffer used in the current render pass instance</usage>
                 <usage>If the &lt;&lt;features-features-inheritedQueries,inherited queries&gt;&gt; feature is not enabled, pname:commandBuffer mustnot: have any queries &lt;&lt;queries-operation-active,active&gt;&gt;</usage>
-                <usage>If pname:commandBuffer has a ename:VK_QUERY_TYPE_OCCLUSION query &lt;&lt;queries-operation-active,active&gt;&gt;, then each element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferBeginInfo::pname:occlusionQueryEnable set to ename:VK_TRUE</usage>
-                <usage>If pname:commandBuffer has a ename:VK_QUERY_TYPE_OCCLUSION query &lt;&lt;queries-operation-active,active&gt;&gt;, then each element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferBeginInfo::pname:queryFlags having all bits set that are set for the query</usage>
+                <usage>If pname:commandBuffer has a ename:VK_QUERY_TYPE_OCCLUSION query &lt;&lt;queries-operation-active,active&gt;&gt;, then each element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferInheritanceInfo::pname:occlusionQueryEnable set to ename:VK_TRUE</usage>
+                <usage>If pname:commandBuffer has a ename:VK_QUERY_TYPE_OCCLUSION query &lt;&lt;queries-operation-active,active&gt;&gt;, then each element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferInheritanceInfo::pname:queryFlags having all bits set that are set for the query</usage>
                 <usage>If pname:commandBuffer has a ename:VK_QUERY_TYPE_PIPELINE_STATISTICS query &lt;&lt;queries-operation-active,active&gt;&gt;, then each element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferInheritanceInfo::pname:pipelineStatistics having all bits set that are set in the sname:VkQueryPool the query uses</usage>
                 <usage>Any given element of pname:pCommandBuffers mustnot: begin any query types that are &lt;&lt;queries-operation-active,active&gt;&gt; in pname:commandBuffer</usage>
             </validity>
@@ -4653,8 +4692,8 @@
             <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
             <param><type>uint32_t</type>* <name>pImageIndex</name></param>
             <validity>
-                <usage>If pname:semaphore is not sname:VK_NULL_HANDLE it must: be unsignaled</usage>
-                <usage>If pname:fence is not sname:VK_NULL_HANDLE it must: be unsignaled and mustnot: be associated with any other queue command that has not yet completed execution on that queue</usage>
+                <usage>If pname:semaphore is not dlink:VK_NULL_HANDLE it must: be unsignaled</usage>
+                <usage>If pname:fence is not dlink:VK_NULL_HANDLE it must: be unsignaled and mustnot: be associated with any other queue command that has not yet completed execution on that queue</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_SUBOPTIMAL_KHR" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST,VK_ERROR_OUT_OF_DATE_KHR,VK_ERROR_SURFACE_LOST_KHR">
@@ -4792,9 +4831,8 @@
             <proto><type>void</type> <name>vkCmdDebugMarkerEndEXT</name></proto>
             <param><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <validity>
-              <usage>There must: be an outstanding flink:vkCmdDebugMarkerBeginEXT command prior to the fname:vkCmdDebugMarkerEndEXT on the queue that pname:commandBuffer is submitted to.</usage>
-              <usage>If the matching flink:vkCmdDebugMarkerBeginEXT command was in a secondary command buffer, the fname:vkCmdDebugMarkerEndEXT must be in the same pname:commandBuffer.</usage>
-
+                <usage>There must: be an outstanding flink:vkCmdDebugMarkerBeginEXT command prior to the fname:vkCmdDebugMarkerEndEXT on the queue that pname:commandBuffer is submitted to.</usage>
+                <usage>If the matching flink:vkCmdDebugMarkerBeginEXT command was in a secondary command buffer, the fname:vkCmdDebugMarkerEndEXT must be in the same pname:commandBuffer.</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -5034,7 +5072,7 @@
         </require>
     </feature>
 
-    <!-- SECTION: Vulkan extension interface definitions (none yet) -->
+    <!-- SECTION: Vulkan extension interface definitions -->
     <extensions>
             <!-- WSI extensions -->
         <extension name="VK_KHR_surface" number="1" supported="vulkan">
@@ -5099,6 +5137,7 @@
                 <enum offset="1" dir="-" extends="VkResult"             name="VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"/>
                 <type name="VkDisplayPresentInfoKHR"/>
                 <command name="vkCreateSharedSwapchainsKHR"/>
+                <usage command="vkQueuePresentKHR">If more than one member of 'pSwapchains' was created from a display surface, all display surfaces referenced that refer to the same display must: use the same display mode.</usage>
             </require>
         </extension>
         <extension name="VK_KHR_xlib_surface" number="5" protect="VK_USE_PLATFORM_XLIB_KHR" supported="vulkan">
@@ -5175,7 +5214,7 @@
         </extension>
         <extension name="VK_EXT_debug_report" number="12" author="Google, Inc." contact="Courtney Goeltzenleuchter @courtney" supported="vulkan">
             <require>
-                <enum value="2"                                         name="VK_EXT_DEBUG_REPORT_SPEC_VERSION"/>
+                <enum value="3"                                         name="VK_EXT_DEBUG_REPORT_SPEC_VERSION"/>
                 <enum value="&quot;VK_EXT_debug_report&quot;"           name="VK_EXT_DEBUG_REPORT_EXTENSION_NAME"/>
                 <enum offset="0" extends="VkStructureType"              name="VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT"/>
                 <enum offset="1" dir="-" extends="VkResult"             name="VK_ERROR_VALIDATION_FAILED_EXT"/>
@@ -5205,7 +5244,7 @@
             <require>
                 <enum value="1"                                         name="VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION"/>
                 <enum value="&quot;VK_KHR_sampler_mirror_clamp_to_edge&quot;"             name="VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME"/>
-                <enum value="4" extends="VkSamplerAddressMode"          name="VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE" comment="Note that this defines what was previously a core enum, and so uses the 'value' attribute rather than 'offset', and doesn't have a suffix. This is a special case, and should not be repeated"/>
+                <enum value="4" extends="VkSamplerAddressMode"          name="VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE" comment="Note that this defines what was previously a core enum, and so uses the 'value' attribute rather than 'offset', and does not have a suffix. This is a special case, and should not be repeated"/>
             </require>
         </extension>
         <extension name="VK_IMG_filter_cubic" number="16" author="IMG" contact="Tobias Hector @tobias" supported="vulkan">
@@ -5230,16 +5269,16 @@
                 <usage struct="VkSamplerCreateInfo">If either pname:magFilter or pname:minFilter is ename:VK_FILTER_CUBIC_IMG, pname:anisotropyEnable must: be ename:VK_FALSE</usage>
             </require>
         </extension>
-        <extension name="VK_AMD_extension_1" number="17" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+        <extension name="VK_AMD_extension_17" number="17" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
             <require>
-                <enum value="0"                                         name="VK_AMD_EXTENSION_1_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_extension_1&quot;"            name="VK_AMD_EXTENSION_1_EXTENSION_NAME"/>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_17_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_17&quot;"           name="VK_AMD_EXTENSION_17_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_AMD_extension_2" number="18" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+        <extension name="VK_AMD_extension_18" number="18" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
             <require>
-                <enum value="0"                                         name="VK_AMD_EXTENSION_2_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_extension_2&quot;"            name="VK_AMD_EXTENSION_2_EXTENSION_NAME"/>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_18_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_18&quot;"           name="VK_AMD_EXTENSION_18_EXTENSION_NAME"/>
             </require>
         </extension>
         <extension name="VK_AMD_rasterization_order" number="19" author="AMD" contact="Daniel Rakos @aqnuep" supported="vulkan">
@@ -5251,22 +5290,22 @@
                 <type name="VkPipelineRasterizationStateRasterizationOrderAMD"/>
             </require>
         </extension>
-        <extension name="VK_AMD_extension_4" number="20" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+        <extension name="VK_AMD_extension_20" number="20" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
             <require>
-                <enum value="0"                                         name="VK_AMD_EXTENSION_4_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_extension_4&quot;"            name="VK_AMD_EXTENSION_4_EXTENSION_NAME"/>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_20_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_20&quot;"           name="VK_AMD_EXTENSION_20_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_AMD_extension_5" number="21" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+        <extension name="VK_AMD_shader_trinary_minmax" number="21" author="AMD" contact="quentin.lin@amd.com" supported="vulkan">
             <require>
-                <enum value="0"                                         name="VK_AMD_EXTENSION_5_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_extension_5&quot;"            name="VK_AMD_EXTENSION_5_EXTENSION_NAME"/>
+                <enum value="1"                                         name="VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_shader_trinary_minmax&quot;"  name="VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_AMD_extension_6" number="22" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+        <extension name="VK_AMD_shader_explicit_vertex_parameter" number="22" author="AMD" contact="quentin.lin@amd.com" supported="vulkan">
             <require>
-                <enum value="0"                                         name="VK_AMD_EXTENSION_6_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_extension_6&quot;"            name="VK_AMD_EXTENSION_6_EXTENSION_NAME"/>
+                <enum value="1"                                                   name="VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_shader_explicit_vertex_parameter&quot;" name="VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME"/>
             </require>
         </extension>
         <extension name="VK_EXT_debug_marker" number="23" author="Baldur Karlsson" contact="baldurk@baldurk.org" supported="vulkan">
@@ -5286,5 +5325,196 @@
                 <command name="vkCmdDebugMarkerInsertEXT"/>
             </require>
         </extension>
+        <extension name="VK_AMD_extension_24" number="24" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_24_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_24&quot;"           name="VK_AMD_EXTENSION_24_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_25" number="25" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_25_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_25&quot;"           name="VK_AMD_EXTENSION_25_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_gcn_shader" number="26" author="AMD" contact="dominik.witczak@amd.com" supported="vulkan">
+            <require>
+                <enum value="1"                                        name="VK_AMD_GCN_SHADER_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_gcn_shader&quot;"            name="VK_AMD_GCN_SHADER_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NV_dedicated_allocation" number="27" author="NVIDIA" contact="Jeff Bolz @jbolz" supported="vulkan">
+            <require>
+                <enum value="1"                                         name="VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION"/>
+                <enum value="&quot;VK_NV_dedicated_allocation&quot;" name="VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME"/>
+                <enum offset="0" extends="VkStructureType"              name="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV"/>
+                <enum offset="1" extends="VkStructureType"              name="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV"/>
+                <enum offset="2" extends="VkStructureType"              name="VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV"/>
+                <type name="VkDedicatedAllocationImageCreateInfoNV"/>
+                <type name="VkDedicatedAllocationBufferCreateInfoNV"/>
+                <type name="VkDedicatedAllocationMemoryAllocateInfoNV"/>
+                <usage command="vkBindBufferMemory">If pname:buffer was created with sname:VkDedicatedAllocationBufferCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE, pname:memory must: have been created with sname:VkDedicatedAllocationMemoryAllocateInfoNV::pname:buffer equal to pname:buffer and pname:memoryOffset must: be zero.</usage>
+                <usage command="vkBindBufferMemory">If pname:buffer was not created with sname:VkDedicatedAllocationBufferCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE, pname:memory must: not have been allocated dedicated for a specific buffer or image</usage>
+                <usage command="vkBindImageMemory">If pname:image was created with sname:VkDedicatedAllocationImageCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE, pname:memory must: have been created with sname:VkDedicatedAllocationMemoryAllocateInfoNV::pname:image equal to pname:image and pname:memoryOffset must: be zero.</usage>
+                <usage command="vkBindImageMemory">If pname:image was not created with sname:VkDedicatedAllocationImageCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE, pname:memory must: not have been allocated dedicated for a specific buffer or image</usage>
+
+            </require>
+        </extension>
+        <extension name="VK_EXT_extension_28" number="28" author="NVIDIA" contact="Piers Daniell @pdaniell" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_EXT_EXTENSION_28_SPEC_VERSION"/>
+                <enum value="&quot;VK_NV_extension_28&quot;"            name="VK_EXT_EXTENSION_28_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NVX_extension_29" number="29" author="NVIDIA" contact="Jeff Juliano @jjuliano" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NVX_EXTENSION_29_SPEC_VERSION"/>
+                <enum value="&quot;VK_NVX_extension_29&quot;"           name="VK_NVX_EXTENSION_29_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NVX_extension_30" number="30" author="NVIDIA" contact="Jeff Juliano @jjuliano" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NVX_EXTENSION_30_SPEC_VERSION"/>
+                <enum value="&quot;VK_NVX_extension_30&quot;"           name="VK_NVX_EXTENSION_30_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NVX_extension_31" number="31" author="NVIDIA" contact="Jeff Juliano @jjuliano" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NVX_EXTENSION_31_SPEC_VERSION"/>
+                <enum value="&quot;VK_NVX_extension_31&quot;"           name="VK_NVX_EXTENSION_31_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_32" number="32" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_32_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_32&quot;"           name="VK_AMD_EXTENSION_32_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_33" number="33" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_33_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_33&quot;"           name="VK_AMD_EXTENSION_33_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_34" number="34" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_34_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_34&quot;"           name="VK_AMD_EXTENSION_34_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_35" number="35" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_35_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_35&quot;"           name="VK_AMD_EXTENSION_35_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_36" number="36" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_36_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_36&quot;"           name="VK_AMD_EXTENSION_36_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_37" number="37" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_37_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_37&quot;"           name="VK_AMD_EXTENSION_37_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_38" number="38" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_38_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_38&quot;"           name="VK_AMD_EXTENSION_38_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_39" number="39" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_39_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_39&quot;"           name="VK_AMD_EXTENSION_39_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_40" number="40" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_40_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_40&quot;"           name="VK_AMD_EXTENSION_40_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_41" number="41" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_41_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_41&quot;"           name="VK_AMD_EXTENSION_41_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_42" number="42" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_42_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_42&quot;"           name="VK_AMD_EXTENSION_42_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_43" number="43" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_43_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_43&quot;"           name="VK_AMD_EXTENSION_43_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_44" number="44" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_44_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_44&quot;"           name="VK_AMD_EXTENSION_44_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_45" number="45" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_45_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_45&quot;"           name="VK_AMD_EXTENSION_45_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_46" number="46" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_46_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_46&quot;"           name="VK_AMD_EXTENSION_46_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_AMD_extension_47" number="47" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_AMD_EXTENSION_47_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_extension_47&quot;"           name="VK_AMD_EXTENSION_47_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NVX_extension_48" number="48" author="NVIDIA" contact="James Jones @cubanismo" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NVX_EXTENSION_48_SPEC_VERSION"/>
+                <enum value="&quot;VK_NVX_extension_48&quot;"           name="VK_NVX_EXTENSION_48_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_GOOGLE_extension_49" number="49" author="GOOGLE" contact="Jean-Francois Roy @jfroy" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_GOOGLE_EXTENSION_49_SPEC_VERSION"/>
+                <enum value="&quot;VK_GOOGLE_extension_49&quot;"        name="VK_GOOGLE_EXTENSION_49_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_GOOGLE_extension_50" number="50" author="GOOGLE" contact="Jean-Francois Roy @jfroy" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_GOOGLE_EXTENSION_50_SPEC_VERSION"/>
+                <enum value="&quot;VK_GOOGLE_extension_50&quot;"        name="VK_GOOGLE_EXTENSION_50_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NVX_extension_51" number="51" author="NVIDIA" contact="James Jones @cubanismo" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NVX_EXTENSION_51_SPEC_VERSION"/>
+                <enum value="&quot;VK_NVX_extension_51&quot;"           name="VK_NVX_EXTENSION_51_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NVX_extension_52" number="52" author="NVIDIA" contact="James Jones @cubanismo" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NVX_EXTENSION_52_SPEC_VERSION"/>
+                <enum value="&quot;VK_NVX_extension_52&quot;"           name="VK_NVX_EXTENSION_52_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NV_extension_53" number="53" author="NVIDIA" contact="Jeff Bolz @jbolz" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NV_EXTENSION_53_SPEC_VERSION"/>
+                <enum value="&quot;VK_NV_extension_53&quot;"            name="VK_NV_EXTENSION_53_EXTENSION_NAME"/>
+            </require>
+        </extension>
     </extensions>
 </registry>
diff --git a/vk_helper.py b/vk_helper.py
index ab99f63..5a36fbb 100755
--- a/vk_helper.py
+++ b/vk_helper.py
@@ -1046,7 +1046,7 @@
                         sh_funcs.append('    ss[%u].str("");' % index)
             # Now print one-line info for all data members
             index = 0
-            final_str = ''
+            final_str = []
             for m in sorted(self.struct_dict[s]):
                 if not is_type(self.struct_dict[s][m]['type'], 'enum'):
                     if is_type(self.struct_dict[s][m]['type'], 'struct') and not self.struct_dict[s][m]['ptr']:
@@ -1106,12 +1106,12 @@
                     # For single enum just print the string representation
                     else:
                         value_print = 'string_%s(pStruct->%s)' % (self.struct_dict[s][m]['type'], self.struct_dict[s][m]['name'])
-                final_str += ' + prefix + "%s = " + %s + "\\n"' % (self.struct_dict[s][m]['name'], value_print)
-            final_str = final_str[3:] # strip off the initial ' + '
+                final_str.append('+ prefix + "%s = " + %s + "\\n"' % (self.struct_dict[s][m]['name'], value_print))
             if 0 != num_stps: # Append data for any embedded structs
-                final_str += " + %s" % " + ".join(['stp_strs[%u]' % n for n in reversed(range(num_stps))])
+                final_str.append("+ %s" % " + ".join(['stp_strs[%u]' % n for n in reversed(range(num_stps))]))
             sh_funcs.append('%s' % lineinfo.get())
-            sh_funcs.append('    final_str = %s;' % final_str)
+            for final_str_part in final_str:
+                sh_funcs.append('    final_str = final_str %s;' % final_str_part)
             sh_funcs.append('    return final_str;\n}')
 
             # End of platform wrapped section
@@ -1563,7 +1563,7 @@
 
     # If struct has sType or ptr members, generate safe type
     def _hasSafeStruct(self, s):
-        exceptions = ['VkPhysicalDeviceFeatures', 'VkPipelineColorBlendStateCreateInfo', 'VkDebugMarkerMarkerInfoEXT']
+        exceptions = ['VkPhysicalDeviceFeatures']
         if s in exceptions:
             return False
         if 'sType' == self.struct_dict[s][0]['name']:
@@ -1571,6 +1571,9 @@
         for m in self.struct_dict[s]:
             if self.struct_dict[s][m]['ptr']:
                 return True
+        inclusions = ['VkDisplayPlanePropertiesKHR', 'VkDisplayModePropertiesKHR', 'VkDisplayPropertiesKHR']
+        if s in inclusions:
+            return True
         return False
 
     def _generateSafeStructHeader(self):
@@ -1641,6 +1644,7 @@
                 ss_src.append('#ifdef %s' % ifdef_dict[s])
             ss_name = self._getSafeStructName(s)
             init_list = '' # list of members in struct constructor initializer
+            default_init_list = '' # Default constructor just inits ptrs to nullptr in initializer
             init_func_txt = '' # Txt for initialize() function that takes struct ptr and inits members
             construct_txt = '' # Body of constuctor as well as body of initialize() func following init_func_txt
             destruct_txt = ''
@@ -1695,6 +1699,7 @@
                         init_list += '\n\t%s(pInStruct->%s),' % (m_name, m_name)
                         init_func_txt += '    %s = pInStruct->%s;\n' % (m_name, m_name)
                     else:
+                        default_init_list += '\n\t%s(nullptr),' % (m_name)
                         init_list += '\n\t%s(nullptr),' % (m_name)
                         init_func_txt += '    %s = nullptr;\n' % (m_name)
                         if 'pNext' != m_name and 'void' not in m_type:
@@ -1713,23 +1718,30 @@
                                 destruct_txt += '    if (%s)\n' % (m_name)
                                 destruct_txt += '        delete[] %s;\n' % (m_name)
                 elif self.struct_dict[s][m]['array']:
-                    # Init array ptr to NULL
-                    init_list += '\n\t%s(NULL),' % (m_name)
-                    init_func_txt += '    %s = NULL;\n' % (m_name)
-                    array_element = 'pInStruct->%s[i]' % (m_name)
-                    if is_type(self.struct_dict[s][m]['type'], 'struct') and self._hasSafeStruct(self.struct_dict[s][m]['type']):
-                        array_element = '%s(&pInStruct->%s[i])' % (self._getSafeStructName(self.struct_dict[s][m]['type']), m_name)
-                    construct_txt += '    if (%s && pInStruct->%s) {\n' % (self.struct_dict[s][m]['array_size'], m_name)
-                    construct_txt += '        %s = new %s[%s];\n' % (m_name, m_type, self.struct_dict[s][m]['array_size'])
-                    destruct_txt += '    if (%s)\n' % (m_name)
-                    destruct_txt += '        delete[] %s;\n' % (m_name)
-                    construct_txt += '        for (uint32_t i=0; i<%s; ++i) {\n' % (self.struct_dict[s][m]['array_size'])
-                    if 'safe_' in m_type:
-                        construct_txt += '            %s[i].initialize(&pInStruct->%s[i]);\n' % (m_name, m_name)
+                    if not self.struct_dict[s][m]['dyn_array']:
+                        # Handle static array case
+                        construct_txt += '    for (uint32_t i=0; i<%s; ++i) {\n' % (self.struct_dict[s][m]['array_size'])
+                        construct_txt += '        %s[i] = pInStruct->%s[i];\n' % (m_name, m_name)
+                        construct_txt += '    }\n'
                     else:
-                        construct_txt += '            %s[i] = %s;\n' % (m_name, array_element)
-                    construct_txt += '        }\n'
-                    construct_txt += '    }\n'
+                        # Init array ptr to NULL
+                        default_init_list += '\n\t%s(nullptr),' % (m_name)
+                        init_list += '\n\t%s(nullptr),' % (m_name)
+                        init_func_txt += '    %s = nullptr;\n' % (m_name)
+                        array_element = 'pInStruct->%s[i]' % (m_name)
+                        if is_type(self.struct_dict[s][m]['type'], 'struct') and self._hasSafeStruct(self.struct_dict[s][m]['type']):
+                            array_element = '%s(&pInStruct->%s[i])' % (self._getSafeStructName(self.struct_dict[s][m]['type']), m_name)
+                        construct_txt += '    if (%s && pInStruct->%s) {\n' % (self.struct_dict[s][m]['array_size'], m_name)
+                        construct_txt += '        %s = new %s[%s];\n' % (m_name, m_type, self.struct_dict[s][m]['array_size'])
+                        destruct_txt += '    if (%s)\n' % (m_name)
+                        destruct_txt += '        delete[] %s;\n' % (m_name)
+                        construct_txt += '        for (uint32_t i=0; i<%s; ++i) {\n' % (self.struct_dict[s][m]['array_size'])
+                        if 'safe_' in m_type:
+                            construct_txt += '            %s[i].initialize(&pInStruct->%s[i]);\n' % (m_name, m_name)
+                        else:
+                            construct_txt += '            %s[i] = %s;\n' % (m_name, array_element)
+                        construct_txt += '        }\n'
+                        construct_txt += '    }\n'
                 elif self.struct_dict[s][m]['ptr']:
                     construct_txt += '    if (pInStruct->%s)\n' % (m_name)
                     construct_txt += '        %s = new %s(pInStruct->%s);\n' % (m_name, m_type, m_name)
@@ -1748,7 +1760,9 @@
             if s in custom_construct_txt:
                 construct_txt = custom_construct_txt[s]
             ss_src.append("\n%s::%s(const %s* pInStruct) : %s\n{\n%s}" % (ss_name, ss_name, s, init_list, construct_txt))
-            ss_src.append("\n%s::%s() {}" % (ss_name, ss_name))
+            if '' != default_init_list:
+                default_init_list = " : %s" % (default_init_list[:-1])
+            ss_src.append("\n%s::%s()%s\n{}" % (ss_name, ss_name, default_init_list))
             # Create slight variation of init and construct txt for copy constructor that takes a src object reference vs. struct ptr
             copy_construct_init = init_func_txt.replace('pInStruct->', 'src.')
             copy_construct_txt = construct_txt.replace(' (pInStruct->', ' (src.') # Exclude 'if' blocks from next line
diff --git a/vk_layer_documentation_generate.py b/vk_layer_documentation_generate.py
index 2dd05ac..ca67a12 100755
--- a/vk_layer_documentation_generate.py
+++ b/vk_layer_documentation_generate.py
@@ -54,33 +54,33 @@
                                  'generated' : False,
                                  'error_enum' : 'DRAW_STATE_ERROR'},
                  'shader_checker' : {'header' : 'layers/core_validation_error_enums.h',
-                                 'source' : 'layers/core_validation.cpp',
-                                 'generated' : False,
-                                 'error_enum' : 'SHADER_CHECKER_ERROR'},
+                                     'source' : 'layers/core_validation.cpp',
+                                     'generated' : False,
+                                     'error_enum' : 'SHADER_CHECKER_ERROR'},
                  'mem_tracker' : {'header' : 'layers/core_validation_error_enums.h',
                                   'source' : 'layers/core_validation.cpp',
                                   'generated' : False,
                                   'error_enum' : 'MEM_TRACK_ERROR'},
+                 'device_limits' : {'header' : 'layers/core_validation_error_enums.h',
+                                    'source' : 'layers/core_validation.cpp',
+                                    'generated' : False,
+                                    'error_enum' : 'DEV_LIMITS_ERROR',},
+                 'object_tracker' : {'header' : 'layers/object_tracker.h',
+                                     'source' : 'layers/object_tracker.cpp',
+                                     'generated' : False,
+                                     'error_enum' : 'OBJECT_TRACK_ERROR',},
                  'threading' : {'header' : 'layers/threading.h',
                                 'source' : 'dbuild/layers/threading.cpp',
                                 'generated' : True,
                                 'error_enum' : 'THREADING_CHECKER_ERROR'},
-                 'object_tracker' : {'header' : 'layers/object_tracker.h',
-                                'source' : 'dbuild/layers/object_tracker.cpp',
-                                'generated' : True,
-                                'error_enum' : 'OBJECT_TRACK_ERROR',},
-                 'device_limits' : {'header' : 'layers/device_limits.h',
-                                    'source' : 'layers/device_limits.cpp',
-                                    'generated' : False,
-                                    'error_enum' : 'DEV_LIMITS_ERROR',},
                  'image' : {'header' : 'layers/image.h',
                             'source' : 'layers/image.cpp',
                             'generated' : False,
                             'error_enum' : 'IMAGE_ERROR',},
                  'swapchain' : {'header' : 'layers/swapchain.h',
-                            'source' : 'layers/swapchain.cpp',
-                            'generated' : False,
-                            'error_enum' : 'SWAPCHAIN_ERROR',},
+                                'source' : 'layers/swapchain.cpp',
+                                'generated' : False,
+                                'error_enum' : 'SWAPCHAIN_ERROR',},
                  'parameter_validation' : {'header' : 'layers/parameter_validation_utils.h',
                                            'source' : 'layers/parameter_validation.cpp',
                                            'generated' : False,
@@ -263,9 +263,7 @@
                         detail_sections = line.split('|')
                         #print("Details elements from line %s: %s" % (line, detail_sections))
                         check_name = '%s%s' % (enum_prefix, detail_sections[3].strip())
-                        if '_NA' in check_name:
-                            # TODO : Should clean up these NA checks in the doc, skipping them for now
-                            continue
+
                         self.enum_list.append(check_name)
                         self.layer_doc_dict[layer_name][check_name] = {}
                         self.layer_doc_dict[layer_name][check_name]['summary_txt'] = detail_sections[1].strip()
@@ -306,6 +304,8 @@
         # Count number of errors found and return it
         errors_found = 0
         warnings_found = 0
+        # A few checks that are allowed to not have tests
+        no_test_checks = ['DRAWSTATE_INTERNAL_ERROR', 'DRAWSTATE_OUT_OF_MEMORY', 'MEMTRACK_INTERNAL_ERROR', 'OBJTRACK_INTERNAL_ERROR']
         # First we'll go through the doc datastructures and flag any issues
         for chk in self.enum_list:
             doc_layer_found = False
@@ -350,7 +350,8 @@
                                 break
                     elif test not in tests_set and not chk.endswith('_NONE'):
                         if test == 'TODO':
-                            warnings_found += 1
+                            if chk not in no_test_checks:
+                                warnings_found += 1
                         else:
                             print(self.txt_color.red() + 'Validation check %s has missing or invalid test : %s' % (chk, test))
                             errors_found += 1
diff --git a/vulkan.py b/vulkan.py
old mode 100755
new mode 100644
index a623f4a..97d8706
--- a/vulkan.py
+++ b/vulkan.py
@@ -883,7 +883,7 @@
              Param("VkBuffer", "dstBuffer"),
              Param("VkDeviceSize", "dstOffset"),
              Param("VkDeviceSize", "dataSize"),
-             Param("const uint32_t*", "pData")]),
+             Param("const void*", "pData")]),
 
         Proto("void", "CmdFillBuffer",
             [Param("VkCommandBuffer", "commandBuffer"),
@@ -1054,6 +1054,54 @@
     ],
 )
 
+ext_khr_display = Extension(
+    name="VK_KHR_display",
+    headers=["vulkan/vulkan.h"],
+    objects=['VkSurfaceKHR', 'VkDisplayModeKHR'],
+    protos=[
+        Proto("VkResult", "GetPhysicalDeviceDisplayPropertiesKHR",
+            [Param("VkPhysicalDevice", "physicalDevice"),
+             Param("uint32_t*", "pPropertyCount"),
+             Param("VkDisplayPropertiesKHR*", "pProperties")]),
+
+        Proto("VkResult", "GetPhysicalDeviceDisplayPlanePropertiesKHR",
+            [Param("VkPhysicalDevice", "physicalDevice"),
+             Param("uint32_t*", "pPropertyCount"),
+             Param("VkDisplayPlanePropertiesKHR*", "pProperties")]),
+
+        Proto("VkResult", "GetDisplayPlaneSupportedDisplaysKHR",
+            [Param("VkPhysicalDevice", "physicalDevice"),
+             Param("uint32_t", "planeIndex"),
+             Param("uint32_t*", "pDisplayCount"),
+             Param("VkDisplayKHR*", "pDisplays")]),
+
+        Proto("VkResult", "GetDisplayModePropertiesKHR",
+            [Param("VkPhysicalDevice", "physicalDevice"),
+             Param("VkDisplayKHR", "display"),
+             Param("uint32_t*", "pPropertyCount"),
+             Param("VkDisplayModePropertiesKHR*", "pProperties")]),
+
+        Proto("VkResult", "CreateDisplayModeKHR",
+            [Param("VkPhysicalDevice", "physicalDevice"),
+             Param("VkDisplayKHR", "display"),
+             Param("const VkDisplayModeCreateInfoKHR*", "pCreateInfo"),
+             Param("const VkAllocationCallbacks*", "pAllocator"),
+             Param("VkDisplayModeKHR*", "pMode")]),
+
+        Proto("VkResult", "GetDisplayPlaneCapabilitiesKHR",
+            [Param("VkPhysicalDevice", "physicalDevice"),
+             Param("VkDisplayModeKHR", "mode"),
+             Param("uint32_t", "planeIndex"),
+             Param("VkDisplayPlaneCapabilitiesKHR*", "pCapabilities")]),
+
+        Proto("VkResult", "CreateDisplayPlaneSurfaceKHR",
+            [Param("VkInstance", "instance"),
+             Param("const VkDisplaySurfaceCreateInfoKHR*", "pCreateInfo"),
+             Param("const VkAllocationCallbacks*", "pAllocator"),
+             Param("VkSurfaceKHR*", "pSurface")]),
+    ],
+)
+
 ext_khr_device_swapchain = Extension(
     name="VK_KHR_swapchain",
     headers=["vulkan/vulkan.h"],
@@ -1220,31 +1268,35 @@
 
 import sys
 
-if len(sys.argv) > 3:
-# TODO : Need to clean this up to more seemlessly handle building different targets than the platform you're on
-    if sys.platform.startswith('win32') and sys.argv[1] != 'Android':
-        extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface]
-        extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, lunarg_debug_report]
-    elif sys.platform.startswith('linux') and sys.argv[1] != 'Android':
-        extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface]
-        extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, lunarg_debug_report]
-    else: # android
-        extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface]
-        extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface, lunarg_debug_report]
+if sys.argv[1] == 'AllPlatforms':
+    extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, ext_khr_display, ext_khr_android_surface]
+    extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, ext_khr_display, ext_khr_android_surface, lunarg_debug_report]
+
 else :
-    if sys.argv[1] == 'Win32':
-        extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface]
-        extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, lunarg_debug_report]
-    elif sys.argv[1] == 'Android':
-        extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface]
-        extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface, lunarg_debug_report]
-    elif sys.argv[1] == 'Xcb' or sys.argv[1] == 'Xlib' or sys.argv[1] == 'Wayland' or sys.argv[1] == 'Mir':
-        extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface]
-        extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, lunarg_debug_report]
-    else:
-        print('Error: Undefined DisplayServer')
-        extensions = []
-        extensions_all = []
+    if len(sys.argv) > 3:
+        if sys.platform.startswith('win32') and sys.argv[1] != 'Android':
+            extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, ext_khr_display]
+            extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, ext_khr_display, lunarg_debug_report]
+        elif sys.platform.startswith('linux') and sys.argv[1] != 'Android':
+            extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, ext_khr_display]
+            extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, ext_khr_display, lunarg_debug_report]
+        else: # android
+            extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface]
+            extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface, lunarg_debug_report]
+    else :
+        if sys.argv[1] == 'Win32':
+            extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, ext_khr_display]
+            extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface, ext_khr_display, lunarg_debug_report]
+        elif sys.argv[1] == 'Android':
+            extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface]
+            extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface, lunarg_debug_report]
+        elif sys.argv[1] == 'Xcb' or sys.argv[1] == 'Xlib' or sys.argv[1] == 'Wayland' or sys.argv[1] == 'Mir' or sys.argv[1] == 'Display':
+            extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, ext_khr_display]
+            extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface, ext_khr_display, lunarg_debug_report]
+        else:
+            print('Error: Undefined DisplayServer')
+            extensions = []
+            extensions_all = []
 
 object_dispatch_list = [
     "VkInstance",
@@ -1278,6 +1330,8 @@
     "VkSwapchainKHR",
     "VkSurfaceKHR",
     "VkDebugReportCallbackEXT",
+    "VkDisplayKHR",
+    "VkDisplayModeKHR",
 ]
 
 object_type_list = object_dispatch_list + object_non_dispatch_list
@@ -1292,6 +1346,16 @@
 
 proto_names = [proto.name for proto in protos]
 
+headers_all = []
+objects_all = []
+protos_all = []
+for ext in extensions_all:
+    headers_all.extend(ext.headers)
+    objects_all.extend(ext.objects)
+    protos_all.extend(ext.protos)
+
+proto_all_names = [proto.name for proto in protos_all]
+
 def parse_vk_h(filename):
     # read object and protoype typedefs
     object_lines = []
diff --git a/windowsRuntimeInstaller/ConfigLayersAndVulkanDLL.ps1 b/windowsRuntimeInstaller/ConfigLayersAndVulkanDLL.ps1
index 6291bea..3eadbfd 100644
--- a/windowsRuntimeInstaller/ConfigLayersAndVulkanDLL.ps1
+++ b/windowsRuntimeInstaller/ConfigLayersAndVulkanDLL.ps1
@@ -29,28 +29,26 @@
 #   - Set the layer registry entries to point to the layer json files

 #     in the Vulkan SDK associated with the most recent vulkan*dll.

 #

-# This script takes the following parameters:

+# This script can be called with the following two parameters:

 #   $majorabi : a single string number specifying the major abi version.

 #   $ossize     : an integer indicating if the target is a 64 (64) or 32 (32) bit OS.

 #

 

+# majorabi and ossize are either prepended to this script or specificied as args

 Param(

- [string]$majorabi,

- [int]$ossize

+ [string]$majorabiarg,

+ [int]$ossizearg

 )

+if ($majorabi -eq $null) {

+    $majorabi=$majorabiarg

+}

+if ($ossize -eq $null) {

+    $ossize=$ossizearg

+}

 

-# Start logging

-$log=$Env:Temp+"\VulkanRT"

-New-Item -ItemType Directory -Force -Path $log | Out-Null

-$logascii=$log+"\ConfigLayersAndVulkanDLL.log"

-$log=$log+"\ConfigLayersAndVulkanDLL16.log"

-echo "ConfigLayersAndVulkanDLL.ps1 $majorabi $ossize" >$log

-(Get-Date).ToString() >>$log

-

-$vulkandll = "vulkan-"+$majorabi+".dll"

-$windrive  = $env:SYSTEMDRIVE

-$winfolder = $env:SYSTEMROOT

-$script:VulkanDllList=@()

+function WriteToLog ($x) {

+    echo $x | Out-File -encoding ascii -append -filepath $script:log

+}

 

 function notNumeric ($x) {

     try {

@@ -61,6 +59,34 @@
     }

 }

 

+function setScriptReturnValue($rvalue) {

+    if ($script:scriptReturnValue -eq 0) {

+        $script:scriptReturnValue = $rvalue

+    }

+}

+

+# Clear any pre-existing errors and set default return value

+$Error.Clear();

+$script:scriptReturnValue=0

+

+# Start logging

+$script:log=$Env:Temp+"\ConfigLayersAndVulkanDLL.log"

+Remove-Item $script:log

+

+# Ignore errors related to log file

+$Error.Clear();

+

+WriteToLog "ConfigLayersAndVulkanDLL.ps1 called with inputs of : $majorabi $ossize"

+$startTime=Get-Date

+WriteToLog "Start time : $startTime"

+WriteToLog "Poweshell Version information:"

+WriteToLog $PsVersionTable

+

+$vulkandll = "vulkan-"+$majorabi+".dll"

+$windrive  = $env:SYSTEMDRIVE

+$winfolder = $env:SYSTEMROOT

+$script:VulkanDllList=@()

+

 # The name of the versioned vulkan dll file is one of the following:

 #

 #   vulkan-<majorabi>-<major>-<minor>-<patch>-<buildno>-<prerelease>-<prebuildno>

@@ -96,7 +122,7 @@
 

 function UpdateVulkanSysFolder([string]$dir, [int]$writeSdkName)

 {

-   echo "UpdateVulkanSysFolder $dir $writeSdkName" >>$log

+   WriteToLog "UpdateVulkanSysFolder $dir $writeSdkName"

 

    # Push the current path on the stack and go to $dir

    Push-Location -Path $dir

@@ -108,25 +134,37 @@
    # Find all vulkan dll files in this directory

    dir -name vulkan-$majorabi-*.dll |

    ForEach-Object {

-       echo "File $_" >>$log

+       WriteToLog  "File $_"

        if ($_ -match "=" -or

            $_ -match "@" -or

            $_ -match " " -or

-           ($_.Split('-').count -lt 6)  -or

-           ($_.Split('-').count -gt 8))

+           ($_.Split('-').count -lt 6) -or

+           ($_.Split('-').count -gt 8) -or

+           !$?)

        {

            # If a file name contains "=", "@", or " ", or it contains less then 5 dashes or more than

            # 7 dashes, it wasn't installed by the Vulkan Run Time.

            # Note that we need to use return inside of ForEach-Object is to continue with iteration.

-           echo "Rejected $_ - bad format" >>$log

+           WriteToLog "Ignoring $_ - bad format"

+

+           # Not a real error, so just clear it for now.

+           $Error.Clear();

+

+           # NOTE: Inside a ForEach-Object block, the 'return' call behaves like a 'continue' for a For loop

            return

        }

 

        # If the corresponding vulkaninfo is not present, it wasn't installed by the Vulkan Run Time

        $vulkaninfo=$_ -replace ".dll",".exe"

        $vulkaninfo=$vulkaninfo -replace "vulkan","vulkaninfo"

-       if (-not (Test-Path $vulkaninfo)) {

-           echo "Rejected $_ - vulkaninfo not present" >>$log

+       if (-not (Test-Path $vulkaninfo) -or

+          !$?) {

+           WriteToLog "Rejected $_ - $vulkaninfo not present"

+

+           # Not a real error, so just clear it for now.

+           $Error.Clear();

+

+           # NOTE: Inside a ForEach-Object block, the 'return' call behaves like a 'continue' for a For loop

            return

        }

 

@@ -171,28 +209,62 @@
               $prebuildno="z"*10

           }

        }

-       echo "Version $majorOrig $minorOrig $patchOrig $buildnoOrig $prereleaseOrig $prebuildnoOrig" >>$log

+       WriteToLog "Version $majorOrig $minorOrig $patchOrig $buildnoOrig $prereleaseOrig $prebuildnoOrig"

+       if (!$?) {

+           WriteToLog "Ignoring version $majorOrig $minorOrig $patchOrig $buildnoOrig $prereleaseOrig $prebuildnoOrig"

+

+           # Not a real error, so just clear it for now.

+           $Error.Clear();

+

+           # NOTE: Inside a ForEach-Object block, the 'return' call behaves like a 'continue' for a For loop

+           return

+       }

 

        # Make sure fields that are supposed to be numbers are numbers

        if (notNumeric($major)) {

-           echo "Rejected $_ - bad major" >>$log

+           WriteToLog "Ignoring $_ - bad major"

+

+           # Not a real error, so just clear it for now.

+           $Error.Clear();

+

+           # NOTE: Inside a ForEach-Object block, the 'return' call behaves like a 'continue' for a For loop

            return

        }

        if (notNumeric($minor)) {

-           echo "Rejected $_ - bad minor" >>$log

+           WriteToLog "Ignoring $_ - bad minor"

+

+           # Not a real error, so just clear it for now.

+           $Error.Clear();

+

+           # NOTE: Inside a ForEach-Object block, the 'return' call behaves like a 'continue' for a For loop

            return

        }

        if (notNumeric($patch)) {

-           echo "Rejected $_ - bad patch" >>$log

+           WriteToLog "Ignoring $_ - bad patch"

+

+           # Not a real error, so just clear it for now.

+           $Error.Clear();

+

+           # NOTE: Inside a ForEach-Object block, the 'return' call behaves like a 'continue' for a For loop

            return

        }

        if (notNumeric($buildno)) {

-           echo "Rejected $_ - bad buildno" >>$log

+           WriteToLog "Ignoring $_ - bad buildno"

+

+           # Not a real error, so just clear it for now.

+           $Error.Clear();

+

+           # NOTE: Inside a ForEach-Object block, the 'return' call behaves like a 'continue' for a For loop

            return

        }

        if (notNumeric($prebuildno)) {

            if ($prebuildno -ne "z"*10) {

-               echo "Rejected $_ - bad prebuildno" >>$log

+               WriteToLog "Ignoring $_ - bad prebuildno"

+

+               # Not a real error, so just clear it for now.

+               $Error.Clear();

+

+               # NOTE: Inside a ForEach-Object block, the 'return' call behaves like a 'continue' for a For loop

                return

            }

        }

@@ -205,8 +277,12 @@
        $prebuildno = $prebuildno.padleft(10,'0')

 

        # Add a new element to the $VulkanDllList array

-       echo "Adding $_ to Vulkan dll list " >>$log

+       WriteToLog "Adding $_ to Vulkan dll list "

        $script:VulkanDllList+="$major=$minor=$patch=$buildno=$prebuildno=$prerelease= $_ @$majorOrig@$minorOrig@$patchOrig@$buildnoOrig@$prereleaseOrig@$prebuildnoOrig@"

+       if (!$?) {

+           WriteToLog "Error: UpdateVulkanSysFolder adding DLL $_ to list"

+           setScriptReturnValue(10)

+       }

    }

 

     # If $VulkanDllList contains at least one element, there's at least one vulkan*.dll file.

@@ -216,20 +292,32 @@
 

         # Sort the list. The most recent vulkan-*.dll will be in the last element of the list.

         [array]::sort($script:VulkanDllList)

+        if (!$?) {

+           WriteToLog "Error: UpdateVulkanSysFolder sorting DLL list" 

+           setScriptReturnValue(20)

+        }

 

         # Put the name of the most recent vulkan-*.dll in $mrVulkanDLL.

         # The most recent vulkanDLL is the second word in the last element of the

         # sorted $VulkanDllList. Copy it to $vulkandll.

         $mrVulkanDll=$script:VulkanDllList[-1].Split(' ')[1]

-        echo "copy $mrVulkanDll $vulkandll" >>$log

-        copy $mrVulkanDll $vulkandll

+        WriteToLog "Copying $mrVulkanDll $vulkandll"

+        Copy-Item $mrVulkanDll $vulkandll -force

+        if (!$?) {

+           WriteToLog "Error: UpdateVulkanSysFolder encountered error during copy $mrVulkanDll $vulkandll"

+           setScriptReturnValue(30)

+        }

 

         # Copy the most recent version of vulkaninfo-<abimajor>-*.exe to vulkaninfo.exe.

         # We create the source file name for the copy from $mrVulkanDll.

         $mrVulkaninfo=$mrVulkanDll -replace ".dll",".exe"

         $mrVulkaninfo=$mrVulkaninfo -replace "vulkan","vulkaninfo"

-        echo "copy $mrVulkaninfo vulkaninfo.exe" >>$log

-        copy $mrVulkaninfo vulkaninfo.exe

+        WriteToLog "Copying $mrVulkaninfo vulkaninfo.exe"

+        Copy-Item $mrVulkaninfo vulkaninfo.exe -force

+        if (!$?) {

+           WriteToLog "Error: UpdateVulkanSysFolder encountered error during copy $mrVulkaninfo vulkaninfo.exe"

+           setScriptReturnValue(40)

+        }

 

         # Create the name used in the registry for the SDK associated with $mrVulkanDll.

         $major=$script:VulkanDllList[-1].Split('@')[1]

@@ -246,11 +334,20 @@
         if ($prebuildno -ne "") {

             $sdktempname=$sdktempname + "." + $prebuildno

         }

-        echo "sdkname = $sdktempname" >>$log

+

+        WriteToLog "sdkname = $sdktempname"

+        if (!$?) {

+           WriteToLog "Error: UpdateVulkanSysFolder encountered error generating SDK name"

+           setScriptReturnValue(50)

+        }

     }

 

     # Return to our previous folder

     Pop-Location

+    if (!$?) {

+       WriteToLog "Error: UpdateVulkanSysFolder popping location"

+       setScriptReturnValue(60)

+    }

 

     # Only update the overall script-scope SDK name if we're told to

     if ($writeSdkName -ne 0) {

@@ -262,43 +359,80 @@
 

 # We only care about SYSWOW64 if we're targeting a 64-bit OS

 if ($ossize -eq 64) {

+

     # Update the SYSWOW64 Vulkan DLLS/EXEs

-    echo "Calling UpdateVulkanSysFolder $winfolder\SYSWOW64 0" >>$log

+    WriteToLog "Calling UpdateVulkanSysFolder $winfolder\SYSWOW64 0"

     UpdateVulkanSysFolder $winfolder\SYSWOW64 0

+    if (!$?) {

+        WriteToLog "Error: Calling UpdateVulkanSysFolder for 64-bit OS" 

+        setScriptReturnValue(70)

+    }

 }

 

-# Update the SYSTEM32 Vulkan DLLS/EXEs

-echo "Calling UpdateVulkanSysFolder $winfolder\SYSTEM32 1" >>$log

-UpdateVulkanSysFolder $winfolder\SYSTEM32 1

+# If this is a 64 bit OS and a 32 bit powershell

+if (($ossize -eq 64 ) -and ([IntPtr]::size -eq 4)) {

+

+    # Update the SYSTEM32 Vulkan DLLS/EXEs

+    WriteToLog "Calling UpdateVulkanSysFolder $winfolder\SYSTEM32 1"

+    UpdateVulkanSysFolder $winfolder\SYSNATIVE 1

+    if (!$?) {

+        WriteToLog "Error: Calling UpdateVulkanSysFolder for all OS"

+        setScriptReturnValue(80)

+    }

+

+} else {

+

+    # Update the SYSTEM32 Vulkan DLLS/EXEs

+    WriteToLog "Calling UpdateVulkanSysFolder $winfolder\SYSTEM32 1"

+    UpdateVulkanSysFolder $winfolder\SYSTEM32 1

+    if (!$?) {

+        WriteToLog "Error: Calling UpdateVulkanSysFolder for all OS"

+        setScriptReturnValue(81)

+    }

+}

 

 # Create an array of vulkan sdk install dirs

 

-echo "Creating array of of Vulkan SDK Install dirs" >>$log

+WriteToLog "Creating array of of Vulkan SDK Install dirs"

 $mrVulkanDllInstallDir=""

 $VulkanSdkDirs=@()

-Get-ChildItem -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall |

-   ForEach-Object {

-       $regkey=$_ -replace ".*\\",""

-       if ($_ -match "\\VulkanSDK") {

-           # Get the install path from UninstallString

-           $tmp=Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$regkey -Name UninstallString

-           $tmp=$tmp -replace "\\Uninstall.exe.*",""

-           $tmp=$tmp -replace ".*=.",""

-           echo "Adding $tmp to VulkanSDKDirs" >>$log

-           $VulkanSdkDirs+=$tmp

-           if ($regkey -eq $script:sdkname) {

-               # Save away the sdk install dir for the the most recent vulkandll

-               echo "Setting mrVulkanDllInstallDir to $tmp" >>$log

-               $mrVulkanDllInstallDir=$tmp

-           }

-       }

+$installSDKRegs = @(Get-ChildItem -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall)

+if ($installSDKRegs -ne $null) {

+   ForEach ($curSDKReg in $installSDKRegs) {

+      if ($curSDKReg -ne $null) {

+         $regkey=$curSDKReg -replace ".*\\",""

+         if ($regkey -match "VulkanSDK") {

+             # Get the install path from UninstallString

+             $tmp=Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$regkey -Name UninstallString

+             if (!$? -or $tmp -eq $null) {

+                 WriteToLog "Error: Get-ItemProperty failed for Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$regkey"

+                 $Error.Clear();

+                 continue;

+             }

+             $tmp=$tmp -replace "\\Uninstall.exe.*",""

+             $tmp=$tmp -replace ".*=.",""

+             WriteToLog "Adding $tmp to VulkanSDKDirs"

+             $VulkanSdkDirs+=$tmp

+             if ($regkey -eq $script:sdkname) {

+                 # Save away the sdk install dir for the the most recent vulkandll

+                 WriteToLog "Setting mrVulkanDllInstallDir to $tmp"

+                 $mrVulkanDllInstallDir=$tmp

+             }

+         }

+      }

    }

+}

+if (!$?) {

+    WriteToLog "Error: Failed creating array of of Vulkan SDK Install dirs"

+    setScriptReturnValue(90)

+}

 

 

 # Search list of sdk install dirs for an sdk compatible with $script:sdkname.

 # We go backwards through VulkanDllList to generate SDK names, because we want the most recent SDK.

-if ($mrVulkanDllInstallDir -eq "") {

-    echo "Searching VulkanDllList" >>$log

+

+if ($mrVulkanDllInstallDir -eq "" -and $script:VulkanDllList.Length -gt 0) {

+    WriteToLog "Searching VulkanDllList"

     ForEach ($idx in ($script:VulkanDllList.Length-1)..0) {

         $tmp=$script:VulkanDllList[$idx]

         $vulkanDllMajor=$script:VulkanDllList[$idx].Split('@')[1]

@@ -314,8 +448,13 @@
         if ($vulkanDllPrebuildno) {

             $regEntry=$regEntry+"."+$vulkanDllPrebuildno

         }

-        echo "Comparing $regEntry" >>$log

+        WriteToLog "Comparing $regEntry"

         $rval=Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$regEntry -ErrorAction SilentlyContinue

+        if (!$? -or $rval -eq $null) {

+            WriteToLog "Ignoring $regEntry - corresponding SDK registry entry does not exist"

+            $Error.Clear();

+            continue

+        }

         $instDir=$rval

         $instDir=$instDir -replace "\\Uninstall.exe.*",""

         $instDir=$instDir -replace ".*=.",""

@@ -326,12 +465,16 @@
             $reMinor=$rval.Split('.')[1]

             $rePatch=$rval.Split('.')[2]

             if ($reMajor+$reMinor+$rePatch -eq $vulkanDllMajor+$vulkanDllMinor+$vulkanDllPatch) {

-                echo "Setting mrVulkanDllInstallDir to $instDir" >>$log

+                WriteToLog "Setting mrVulkanDllInstallDir to $instDir"

                 $mrVulkanDllInstallDir=$instDir

                 break

             }

         }

     }

+    if (!$?) {

+        WriteToLog "Failed searching VulkanDLLList"

+        $Error.Clear();

+    }

 }

 

 # Add C:\Vulkan\SDK\0.9.3 to list of SDK install dirs.

@@ -349,239 +492,142 @@
 # Note that we remove only those entries created by Vulkan SDKs. If other

 # layers were installed that are not from an SDK, we don't mess with them.

 

-echo "Removing old layer registry values from HKLM\SOFTWARE\Khronos\Vulkan\ExplicitLayers" >>$log

-Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\ExplicitLayers | Select-Object -ExpandProperty Property |

-   ForEach-Object {

-       $regval=$_

-       ForEach ($sdkdir in $VulkanSdkDirs) {

-          if ($regval -like "$sdkdir\*.json") {

-              Remove-ItemProperty -ErrorAction SilentlyContinue -Path HKLM:\SOFTWARE\Khronos\Vulkan\ExplicitLayers -name $regval

-              echo "Removed registry value $regval" >>$log

-          }

-       }

-   }

+WriteToLog "Removing old layer registry values from HKLM\SOFTWARE\Khronos\Vulkan\ExplicitLayers"

+$regkeys = @(Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\ExplicitLayers | Select-Object -ExpandProperty Property)

+if ($regkeys -ne $null) {

+   ForEach ($regval in $regkeys) {

+       if ($regval -ne $null) {

+           ForEach ($sdkdir in $VulkanSdkDirs) {

+              if ($regval -like "$sdkdir\*.json") {

+                  Remove-ItemProperty -ErrorAction SilentlyContinue -Path HKLM:\SOFTWARE\Khronos\Vulkan\ExplicitLayers -name $regval

+                  if (!$?) {

+                     WriteToLog "Error: Remove-ItemProperty failed for -Path HKLM:\SOFTWARE\Khronos\Vulkan\ExplicitLayers -name $regval"

+                  } else {

+                     WriteToLog "Removed registry value $regval"

+                  }

+              }

+           }

+        }

+    }

+}

+

+if (!$?) {

+    WriteToLog "Error: Failed Removing old layer registry values from HKLM\SOFTWARE\Khronos\Vulkan\ExplicitLayers"

+    setScriptReturnValue(100)

+}

+

 # Remove 32-bit layer registry value if we're targeting a 64-bit OS

 if ($ossize -eq 64) {

-   Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers | Select-Object -ExpandProperty Property |

-      ForEach-Object {

-          $regval=$_

-          ForEach ($sdkdir in $VulkanSdkDirs) {

-             if ($regval -like "$sdkdir\*.json") {

-                 Remove-ItemProperty -ErrorAction SilentlyContinue -Path HKLM:\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers -name $regval

-                 echo "Removed WOW6432Node registry value $regval" >>$log

+   $regkeys = @(Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers | Select-Object -ExpandProperty Property)

+   if ($regkeys -ne $null) {

+      ForEach ($regval in $regkeys) {

+          if ($regval -ne $null) {

+              ForEach ($sdkdir in $VulkanSdkDirs) {

+                 if ($regval -like "$sdkdir\*.json") {

+                    Remove-ItemProperty -ErrorAction SilentlyContinue -Path HKLM:\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers -name $regval

+                    if (!$?) {

+                       WriteToLog "Error: Remove-ItemProperty failed for -Path HKLM:\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers -name $regval"

+                    } else {

+                       WriteToLog "Removed WOW6432Node registry value $regval"

+                    }

+                 }

              }

-          }

+         }

       }

+   }

+

+   if (!$?) {

+      WriteToLog "Error: Failed Removing old layer registry values from HKLM\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers"

+      setScriptReturnValue(110)

+   }

 }

 

 

 # Create layer registry values associated with Vulkan SDK from which $mrVulkanDll is from

 

-echo "Creating new layer registry values" >>$log

+WriteToLog "Creating new layer registry values"

 if ($mrVulkanDllInstallDir -ne "") {

 

     # Create registry keys if they don't exist

     if (-not (Test-Path -Path HKLM:\SOFTWARE\Khronos\Vulkan\ExplicitLayers)) {

-        echo "Creating new registry key HKLM\SOFTWARE\Khronos\Vulkan\ExplicitLayers" >>$log

+        WriteToLog "Creating new registry key HKLM\SOFTWARE\Khronos\Vulkan\ExplicitLayers"

         New-Item -Force -ErrorAction SilentlyContinue -Path HKLM:\SOFTWARE\Khronos\Vulkan\ExplicitLayers | out-null

+        if (!$?) {

+            WriteToLog "Error: Failed creating HKLM\SOFTWARE\Khronos\Vulkan\ExplicitLayers"

+            setScriptReturnValue(120)

+        }

     }

     if ($ossize -eq 64) {

         if (-not (Test-Path -Path HKLM:\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers)) {

-            echo "Creating new registry key HKLM\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers" >>$log

+            WriteToLog "Creating new registry key HKLM\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers"

             New-Item -Force -ErrorAction SilentlyContinue -Path HKLM:\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers | out-null

-       }

+            if (!$?) {

+                WriteToLog "Error: Failed creating HKLM\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers"

+                setScriptReturnValue(130)

+            }

+        }

     }

 

 

     if ($ossize -eq 64) {

-    

         # Create registry values in normal registry location for 64-bit items on a 64-bit OS

         Get-ChildItem $mrVulkanDllInstallDir\Bin -Filter VkLayer*json |

            ForEach-Object {

-               echo "Creating registry value $mrVulkanDllInstallDir\Bin\$_" >>$log

+               WriteToLog "Creating registry value $mrVulkanDllInstallDir\Bin\$_"

                New-ItemProperty -Path HKLM:\SOFTWARE\Khronos\Vulkan\ExplicitLayers -Name $mrVulkanDllInstallDir\Bin\$_ -PropertyType DWord -Value 0 | out-null

+               if (!$?) {

+                   WriteToLog "Error: Failed creating $mrVulkanDllInstallDir\Bin\$_"

+                   setScriptReturnValue(140)

+               }

+           }

+           if (!$?) {

+               WriteToLog "Error: Failed Get-ChildItem $mrVulkanDllInstallDir\Bin | ForEach-Object "

+               setScriptReturnValue(150)

            }

 

         # Create registry values for the WOW6432Node registry location for 32-bit items on a 64-bit OS

         Get-ChildItem $mrVulkanDllInstallDir\Bin32 -Filter VkLayer*json |

            ForEach-Object {

-               echo "Creating WOW6432Node registry value $mrVulkanDllInstallDir\Bin32\$_" >>$log

+               WriteToLog "Creating WOW6432Node registry value $mrVulkanDllInstallDir\Bin32\$_"

                New-ItemProperty -Path HKLM:\SOFTWARE\WOW6432Node\Khronos\Vulkan\ExplicitLayers -Name $mrVulkanDllInstallDir\Bin32\$_ -PropertyType DWord -Value 0 | out-null

+               if (!$?) {

+                   WriteToLog "Error: Failed creating $mrVulkanDllInstallDir\Bin32\$_"

+                   setScriptReturnValue(160)

+               }

            }

-           

+           if (!$?) {

+               WriteToLog "Error: Failed Get-ChildItem $mrVulkanDllInstallDir\Bin32 | ForEach-Object "

+               setScriptReturnValue(170)

+           }

     } else {

-    

         # Create registry values in normal registry location for 32-bit items on a 32-bit OS

         Get-ChildItem $mrVulkanDllInstallDir\Bin32 -Filter VkLayer*json |

            ForEach-Object {

-               echo "Creating registry value $mrVulkanDllInstallDir\Bin\$_" >>$log

+               WriteToLog "Creating registry value $mrVulkanDllInstallDir\Bin\$_"

                New-ItemProperty -Path HKLM:\SOFTWARE\Khronos\Vulkan\ExplicitLayers -Name $mrVulkanDllInstallDir\Bin32\$_ -PropertyType DWord -Value 0 | out-null

-           }

-    

+               if (!$?) {

+                   WriteToLog "Error: Failed creating $mrVulkanDllInstallDir\Bin\$_"

+                   setScriptReturnValue(180)

+               }

+            }

+            if (!$?) {

+                WriteToLog "Error: Failed Get-ChildItem $mrVulkanDllInstallDir\Bin32 | ForEach-Object "

+                setScriptReturnValue(190)

+            }

     }

 }

 

+# Debug - for testing handling of script failure in installer

+#setScriptReturnValue(200)

+

 # Final log output

-echo "ConfigLayersAndVulkanDLL.ps1 completed" >>$log

-(Get-Date).ToString() >>$log

+WriteToLog "ConfigLayersAndVulkanDLL.ps1 completed, return status is $script:scriptReturnValue"

+$endTime=Get-Date

+WriteToLog "End time: $endTime"

 

-# Convert logfile to ascii

-cat $log | out-File -encoding ascii -filepath $logascii

-remove-item $log

+# Since InstallerRT.nsi runs this script by piping it to powershell.exe, the exit status

+# doesn't seem to be available. So we put in it a file where InstallRT.nsi can retrieve it.

+$statusfile=$Env:Temp+"\ConfigLayersAndVulkanDLL.stat"

+echo $script:scriptReturnValue | Out-File -encoding ascii -filepath $statusfile

 

-

-

-# SIG # Begin signature block

-# MIIcZgYJKoZIhvcNAQcCoIIcVzCCHFMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB

-# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR

-# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUQ4I+TKoMwtXHArekRd5/bX04

-# sreggheVMIIFHjCCBAagAwIBAgIQDmYEpPtQ2iBY4vC2AGq6uzANBgkqhkiG9w0B

-# AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD

-# VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz

-# c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTE1MDQzMDAwMDAwMFoXDTE2MDcw

-# NjEyMDAwMFowZTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCENvbG9yYWRvMRUwEwYD

-# VQQHEwxGb3J0IENvbGxpbnMxFTATBgNVBAoTDEx1bmFyRywgSW5jLjEVMBMGA1UE

-# AxMMTHVuYXJHLCBJbmMuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA

-# jaLJm/Joxsn/IeopiGY3XPeSZeIhjSjSlQUkDyIyDGcBG7CvfiSsXIw3EgdGkjQg

-# yBcW5YsPz9bPGPUjo5go7CwZaRkhW7/LmSkAlx0UAv8EMLuJrAZ3jBNZvpPPqfWd

-# zgi/Rkm2gWQ6eSKouy7IjcLk+EwkeBbB+UBnYfMp0BfCPzR3mPgGAJH6efAmEaqQ

-# FBCrX97joYgDqp3v8u42jALLl/Ict/GNMHLxP+QWagIHIICCRgS6s02OsildLF6R

-# nqJOOG/43f2qUD4Cab65kzlI+0+uQyOl1UlxNxp0XareghGTqECsYA03j64Esxyo

-# 2xrNbV2LJm9crTX6QthxywIDAQABo4IBuzCCAbcwHwYDVR0jBBgwFoAUWsS5eyoK

-# o6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYEFOSdVsqodGWApfCjHtAcn8sAzLBGMA4G

-# A1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzB3BgNVHR8EcDBuMDWg

-# M6Axhi9odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcx

-# LmNybDA1oDOgMYYvaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl

-# ZC1jcy1nMS5jcmwwQgYDVR0gBDswOTA3BglghkgBhv1sAwEwKjAoBggrBgEFBQcC

-# ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBhAYIKwYBBQUHAQEEeDB2

-# MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTgYIKwYBBQUH

-# MAKGQmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1

-# cmVkSURDb2RlU2lnbmluZ0NBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEB

-# CwUAA4IBAQCIt1S8zfvzMQEVmdAssjrwqBaq78xhtGPLjkNF06EvtWoV6VMLI/A6

-# 45KoULsaXeYuszLxNI+OT/b4HfD0e2LxImaTDZRmCLeIs+2pMLSlWDSV4okm8Vk2

-# rObLBlgiI1x0PiMa1le9D832COWM4EJcH7pxM+9JfiHYMLlZbcfNEVgv6Dhhl4MG

-# mOTMTl7vQNNQaJ1coNVf9m5Bez1DV9Iu2Cgd8BHp1oLVCQCHjVv0Ifj48RIPi4SQ

-# khzalrnrf+L/BWRDhpLnxYasazdV5WfrMHurPuBvYUiLQNkU9SqKgRk9XrzDAfMe

-# gPbGybMr0kqtbE/A/cDcTVnvRuTZnhXSMIIFMDCCBBigAwIBAgIQBAkYG1/Vu2Z1

-# U0O1b5VQCDANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM

-# RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQD

-# ExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMTMxMDIyMTIwMDAwWhcN

-# MjgxMDIyMTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQg

-# SW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2Vy

-# dCBTSEEyIEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0B

-# AQEFAAOCAQ8AMIIBCgKCAQEA+NOzHH8OEa9ndwfTCzFJGc/Q+0WZsTrbRPV/5aid

-# 2zLXcep2nQUut4/6kkPApfmJ1DcZ17aq8JyGpdglrA55KDp+6dFn08b7KSfH03sj

-# lOSRI5aQd4L5oYQjZhJUM1B0sSgmuyRpwsJS8hRniolF1C2ho+mILCCVrhxKhwjf

-# DPXiTWAYvqrEsq5wMWYzcT6scKKrzn/pfMuSoeU7MRzP6vIK5Fe7SrXpdOYr/mzL

-# fnQ5Ng2Q7+S1TqSp6moKq4TzrGdOtcT3jNEgJSPrCGQ+UpbB8g8S9MWOD8Gi6CxR

-# 93O8vYWxYoNzQYIH5DiLanMg0A9kczyen6Yzqf0Z3yWT0QIDAQABo4IBzTCCAckw

-# EgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYI

-# KwYBBQUHAwMweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz

-# cC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2lj

-# ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgw

-# OqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ

-# RFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp

-# Q2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwTwYDVR0gBEgwRjA4BgpghkgBhv1sAAIE

-# MCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYI

-# YIZIAYb9bAMwHQYDVR0OBBYEFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB8GA1UdIwQY

-# MBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3DQEBCwUAA4IBAQA+7A1a

-# JLPzItEVyCx8JSl2qB1dHC06GsTvMGHXfgtg/cM9D8Svi/3vKt8gVTew4fbRknUP

-# UbRupY5a4l4kgU4QpO4/cY5jDhNLrddfRHnzNhQGivecRk5c/5CxGwcOkRX7uq+1

-# UcKNJK4kxscnKqEpKBo6cSgCPC6Ro8AlEeKcFEehemhor5unXCBc2XGxDI+7qPjF

-# Emifz0DLQESlE/DmZAwlCEIysjaKJAL+L3J+HNdJRZboWR3p+nRka7LrZkPas7CM

-# 1ekN3fYBIM6ZMWM9CBoYs4GbT8aTEAb8B4H6i9r5gkn3Ym6hU/oSlBiFLpKR6mhs

-# RDKyZqHnGKSaZFHvMIIGajCCBVKgAwIBAgIQAwGaAjr/WLFr1tXq5hfwZjANBgkq

-# hkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j

-# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBB

-# c3N1cmVkIElEIENBLTEwHhcNMTQxMDIyMDAwMDAwWhcNMjQxMDIyMDAwMDAwWjBH

-# MQswCQYDVQQGEwJVUzERMA8GA1UEChMIRGlnaUNlcnQxJTAjBgNVBAMTHERpZ2lD

-# ZXJ0IFRpbWVzdGFtcCBSZXNwb25kZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw

-# ggEKAoIBAQCjZF38fLPggjXg4PbGKuZJdTvMbuBTqZ8fZFnmfGt/a4ydVfiS457V

-# WmNbAklQ2YPOb2bu3cuF6V+l+dSHdIhEOxnJ5fWRn8YUOawk6qhLLJGJzF4o9GS2

-# ULf1ErNzlgpno75hn67z/RJ4dQ6mWxT9RSOOhkRVfRiGBYxVh3lIRvfKDo2n3k5f

-# 4qi2LVkCYYhhchhoubh87ubnNC8xd4EwH7s2AY3vJ+P3mvBMMWSN4+v6GYeofs/s

-# jAw2W3rBerh4x8kGLkYQyI3oBGDbvHN0+k7Y/qpA8bLOcEaD6dpAoVk62RUJV5lW

-# MJPzyWHM0AjMa+xiQpGsAsDvpPCJEY93AgMBAAGjggM1MIIDMTAOBgNVHQ8BAf8E

-# BAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDCCAb8G

-# A1UdIASCAbYwggGyMIIBoQYJYIZIAYb9bAcBMIIBkjAoBggrBgEFBQcCARYcaHR0

-# cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCCAWQGCCsGAQUFBwICMIIBVh6CAVIA

-# QQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABDAGUAcgB0AGkAZgBpAGMA

-# YQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABhAGMAYwBlAHAAdABhAG4A

-# YwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQByAHQAIABDAFAALwBDAFAA

-# UwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBnACAAUABhAHIAdAB5ACAA

-# QQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABsAGkAbQBpAHQAIABsAGkA

-# YQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABpAG4AYwBvAHIAcABvAHIA

-# YQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBlAGYAZQByAGUAbgBjAGUA

-# LjALBglghkgBhv1sAxUwHwYDVR0jBBgwFoAUFQASKxOYspkH7R7for5XDStnAs0w

-# HQYDVR0OBBYEFGFaTSS2STKdSip5GoNL9B6Jwcp9MH0GA1UdHwR2MHQwOKA2oDSG

-# Mmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEu

-# Y3JsMDigNqA0hjJodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1

-# cmVkSURDQS0xLmNybDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6

-# Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMu

-# ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcnQwDQYJKoZIhvcN

-# AQEFBQADggEBAJ0lfhszTbImgVybhs4jIA+Ah+WI//+x1GosMe06FxlxF82pG7xa

-# FjkAneNshORaQPveBgGMN/qbsZ0kfv4gpFetW7easGAm6mlXIV00Lx9xsIOUGQVr

-# NZAQoHuXx/Y/5+IRQaa9YtnwJz04HShvOlIJ8OxwYtNiS7Dgc6aSwNOOMdgv420X

-# Ewbu5AO2FKvzj0OncZ0h3RTKFV2SQdr5D4HRmXQNJsQOfxu19aDxxncGKBXp2JPl

-# VRbwuwqrHNtcSCdmyKOLChzlldquxC5ZoGHd2vNtomHpigtt7BIYvfdVVEADkitr

-# wlHCCkivsNRu4PQUCjob4489yq9qjXvc2EQwggbNMIIFtaADAgECAhAG/fkDlgOt

-# 6gAK6z8nu7obMA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK

-# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV

-# BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBa

-# Fw0yMTExMTAwMDAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy

-# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD

-# ZXJ0IEFzc3VyZWQgSUQgQ0EtMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC

-# ggEBAOiCLZn5ysJClaWAc0Bw0p5WVFypxNJBBo/JM/xNRZFcgZ/tLJz4FlnfnrUk

-# FcKYubR3SdyJxArar8tea+2tsHEx6886QAxGTZPsi3o2CAOrDDT+GEmC/sfHMUiA

-# fB6iD5IOUMnGh+s2P9gww/+m9/uizW9zI/6sVgWQ8DIhFonGcIj5BZd9o8dD3QLo

-# Oz3tsUGj7T++25VIxO4es/K8DCuZ0MZdEkKB4YNugnM/JksUkK5ZZgrEjb7Szgau

-# rYRvSISbT0C58Uzyr5j79s5AXVz2qPEvr+yJIvJrGGWxwXOt1/HYzx4KdFxCuGh+

-# t9V3CidWfA9ipD8yFGCV/QcEogkCAwEAAaOCA3owggN2MA4GA1UdDwEB/wQEAwIB

-# hjA7BgNVHSUENDAyBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEF

-# BQcDBAYIKwYBBQUHAwgwggHSBgNVHSAEggHJMIIBxTCCAbQGCmCGSAGG/WwAAQQw

-# ggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9zc2wtY3Bz

-# LXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUA

-# cwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMA

-# bwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYA

-# IAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQA

-# IAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUA

-# bQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkA

-# dAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAA

-# aABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG

-# /WwDFTASBgNVHRMBAf8ECDAGAQH/AgEAMHkGCCsGAQUFBwEBBG0wazAkBggrBgEF

-# BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRw

-# Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0Eu

-# Y3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v

-# RGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsNC5k

-# aWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMB0GA1UdDgQW

-# BBQVABIrE5iymQftHt+ivlcNK2cCzTAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun

-# pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEARlA+ybcoJKc4HbZbKa9Sz1LpMUer

-# Vlx71Q0LQbPv7HUfdDjyslxhopyVw1Dkgrkj0bo6hnKtOHisdV0XFzRyR4WUVtHr

-# uzaEd8wkpfMEGVWp5+Pnq2LN+4stkMLA0rWUvV5PsQXSDj0aqRRbpoYxYqioM+Sb

-# OafE9c4deHaUJXPkKqvPnHZL7V/CSxbkS3BMAIke/MV5vEwSV/5f4R68Al2o/vsH

-# OE8Nxl2RuQ9nRc3Wg+3nkg2NsWmMT/tZ4CMP0qquAHzunEIOz5HXJ7cW7g/DvXwK

-# oO4sCFWFIrjrGBpN/CohrUkxg0eVd3HcsRtLSxwQnHcUwZ1PL1qVCCkQJjGCBDsw

-# ggQ3AgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx

-# GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNI

-# QTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0ECEA5mBKT7UNogWOLwtgBqursw

-# CQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcN

-# AQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUw

-# IwYJKoZIhvcNAQkEMRYEFAoOC46C6ArmxtlmLsUTidSbkN3rMA0GCSqGSIb3DQEB

-# AQUABIIBADXG8YUKEPQHyMUpBvGWwb5VeZ8oWPyiSSE649GXu5tHDn+N2lhDPngR

-# Cksh4FpF56hP4RgTzH/Nmxf2D4kZUzPCrs2Il1S+U0ZoFpoAwrN8dbnvw2Wvf7ns

-# LZHXKG9eIaMYx6r/nn+VV8qvL/25fZ8oNyIFCYy4FYRLmla5g1+Vmtg6anHj89c+

-# EMSIwR8BR5UlAagfhfKJQHYMz4xkdqMrR6ZDsMHvYjbOg3MILrrdgomH2R5JKAHK

-# IaD3EqM+Tgu8LH1MMt/hIf4RS/lgqT12qM88J64dyhquaM1BUzw5dnwb+h3aAF2O

-# ZJ4IhONECJbJf8wVT8rTUA+6uUm/Y6ihggIPMIICCwYJKoZIhvcNAQkGMYIB/DCC

-# AfgCAQEwdjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw

-# FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBBc3N1

-# cmVkIElEIENBLTECEAMBmgI6/1ixa9bV6uYX8GYwCQYFKw4DAhoFAKBdMBgGCSqG

-# SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE2MDQwNzIxNTM0

-# OFowIwYJKoZIhvcNAQkEMRYEFERKj5qmhGjIIeKV/myZFhJ/EUO7MA0GCSqGSIb3

-# DQEBAQUABIIBAJYQytkxzpn/UVwVJ0tsompGzVKSEgjuqAiI2jA0LiQwWM9iBHpG

-# 8ijDH6Dh+Fqa1JSsynyFixF26SuHeDoY/LX14HhRPDEkBa70qt9h9gc/73f9AzUy

-# eSbxwRhlF/UAyk0E3fbK1of431HxfvcdhnvCIDW8orfiG5v7gS0Mub4C70TlMXTp

-# b6XT1orYqnih9j4EVCYWZwv+EsOADRHW7o1RvIC2gI2dzmAkMSEjehk3we6u8KXI

-# xkggPOXy5O8TFgFdjvKU6XaoTTCklKWFIQIRG9r5m//Qj3jwzwN/03gLPphi6zze

-# 8fAJmClDyH+kHivSSfFnFUB7elvajTvasQE=

-# SIG # End signature block

+exit $script:scriptReturnValue

diff --git a/windowsRuntimeInstaller/InstallerRT.nsi b/windowsRuntimeInstaller/InstallerRT.nsi
index 680a14a..8b9b20e 100644
--- a/windowsRuntimeInstaller/InstallerRT.nsi
+++ b/windowsRuntimeInstaller/InstallerRT.nsi
@@ -27,12 +27,16 @@
 #    x for releases
 #
 !define PRODUCTNAME "VulkanRT"
-!define VERSION_ABI_MAJOR "1"
-!define VERSION_API_MAJOR "1"
-!define VERSION_MINOR "0"
-!define VERSION_PATCH "12"
-!define VERSION_BUILDNO "0.devbuild.1"
-!define PUBLISHER "YourCompany, Inc."
+!ifndef HIDE_VERSION
+  !define VERSION_ABI_MAJOR "1"
+  !define VERSION_API_MAJOR "1"
+  !define VERSION_MINOR "0"
+  !define VERSION_PATCH "12"
+  !define VERSION_BUILDNO "0.devbuild.1"
+!endif
+!ifndef HIDE_PUBLISHER
+  !define PUBLISHER "YourCompany, Inc."
+!endif
 #!define VERSION_BUILDNO "0"
 !define PRODUCTVERSION "${VERSION_API_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_BUILDNO}"
 
@@ -86,10 +90,6 @@
 # Install count
 Var IC
 
-# Error code from powershell script
-Var PsErr
-
-
 #############################################
 # StrRep - string replace
 
@@ -232,16 +232,92 @@
     VIAddVersionKey  "FileDescription" "Vulkan Runtime Installer"
 !endif
 
+
+# Function to run ConfigLayersAndVulkanDll ps script.
+# Return value is in $0 - 0 is success, all else is failure.
+!macro ConfigLayersAndVulkanDLL un
+Function ${un}ConfigLayersAndVulkanDLL
+
+    ${If} ${RunningX64}
+        Strcpy $1 64
+    ${Else}
+        Strcpy $1 32
+    ${Endif}
+
+    # Create the script, the first two lines are the majorabi and ossize.
+    nsExec::ExecToStack 'cmd /k echo $$majorabi=${VERSION_ABI_MAJOR} >"$TEMP\VulkanRT\VulkanRT.ps1"'
+    nsExec::ExecToStack 'cmd /k echo $$ossize=$1 >>"$TEMP\VulkanRT\VulkanRT.ps1"'
+    nsExec::ExecToStack 'cmd /k type ConfigLayersAndVulkanDLL.ps1 >>"$TEMP\VulkanRT\VulkanRT.ps1"'
+
+    # Exectute the script by piping it to powershell.exe. This gets around possible OS
+    # security restrictions on running powershell scripts.
+    nsExec::ExecToStack 'cmd /k type "$TEMP\VulkanRT\VulkanRT.ps1" | powershell -NoProfile -NoLogo -NonInteractive -WindowStyle Hidden -inputformat none -Command -'
+    Delete "$TEMP\VulkanRT\ConfigLayersAndVulkanDLL1.${un}log"
+    Rename "$TEMP\ConfigLayersAndVulkanDLL.log" "$TEMP\VulkanRT\ConfigLayersAndVulkanDLL1.${un}log"
+    pop $0
+
+    # If it failed, try again, with a full path to powershell.exe
+    ${If} $0 != 0
+        nsExec::ExecToStack 'cmd /k type "$TEMP\VulkanRT\VulkanRT.ps1" | "$WINDIR\System32\WindowsPowerShell\v1.0\powershell" -NoProfile -NoLogo -NonInteractive -WindowStyle Hidden -inputformat none -Command -'
+        pop $0
+        Delete "$TEMP\VulkanRT\ConfigLayersAndVulkanDLL2.${un}log"
+        Rename "$TEMP\ConfigLayersAndVulkanDLL.log" "$TEMP\VulkanRT\ConfigLayersAndVulkanDLL2.${un}log"
+    ${Endif}
+
+    # Read the return value of the script and put it in $0, stripping trailing newline
+    FileOpen $1 "$TEMP\ConfigLayersAndVulkanDLL.stat" r
+    ${If} $1 != ""
+        FileRead $1 $2
+        FileClose $1
+        ${StrRep} $3 $2 "$\n" ""
+        ${StrRep} $0 $3 "$\r" ""
+    ${Else}
+       # error
+       StrCpy $0 -1
+    ${Endif}
+
+    # Cleanup
+    Delete "$TEMP\ConfigLayersAndVulkanDLL.stat"
+    Delete "$TEMP\VulkanRT\VulkanRT.ps1"
+
+    # Ignore errors. If something went wrong, the return value will indicate it.
+    ClearErrors
+
+FunctionEnd
+!macroend
+!insertmacro ConfigLayersAndVulkanDLL ""
+!insertmacro ConfigLayersAndVulkanDLL "un."
+
+
+# Function to run diagnostics if ConfigLayersAndVulkanDll ps script failed.
+# On entry $0, contains the return value from ConfigLayersAndVulkanDll.ps1. It shouldn't be changed.
+!macro DiagConfigLayersAndVulkanDLL un
+Function ${un}DiagConfigLayersAndVulkanDLL
+    LogText "ConfigLayersAndVulkanDLL.ps1 rval is $0"
+    nsExec::ExecToStack 'powershell -NoProfile -NoLogo -NonInteractive -WindowStyle Hidden -inputformat none -Command Write-Output Diagnostic0 | Out-File  -encoding ascii -filePath "$TEMP\VulkanRT\Diagnostic0.${un}log"'
+    pop $1
+    LogText "ps cmd rval is $1"
+    nsExec::ExecToStack 'cmd /k echo %PATH% >"$TEMP\VulkanRT\Diagnostic1.${un}log"'
+    pop $1
+    LogText "cmd1 rval is $1"
+    nsExec::ExecToStack 'cmd /k dir "$WINDIR\System32\WindowsPowerShell\v1.0" >"$TEMP\VulkanRT\Diagnostic2.${un}log"'
+    pop $1
+    LogText "cmd2 rval is $1"
+    
+    # Ignore errors
+    ClearErrors
+
+FunctionEnd
+!macroend
+!insertmacro DiagConfigLayersAndVulkanDLL ""
+!insertmacro DiagConfigLayersAndVulkanDLL "un."
+
 # Start default section
 Section
 
     # Turn on logging
     LogSet on
 
-    # Remove contents of temp dir
-    SetOutPath "$TEMP\VulkanRT"
-    RmDir /R "$TEMP\VulkanRT"
-
     # If running on a 64-bit OS machine, disable registry re-direct since we're running as a 32-bit executable.
     ${If} ${RunningX64}
 
@@ -251,6 +327,7 @@
     ${Endif}
 
     # Create our temp directory, with minimal permissions
+    RmDir /R "$TEMP\VulkanRT"
     SetOutPath "$TEMP\VulkanRT"
     AccessControl::DisableFileInheritance $TEMP\VulkanRT
     AccessControl::SetFileOwner $TEMP\VulkanRT "Administrators"
@@ -415,17 +492,6 @@
         StrCpy $1 40
         Call CheckForError
 
-        # Run the ConfigLayersAndVulkanDLL.ps1 script to copy the most recent version of
-        # vulkan-<abimajor>-*.dll to vulkan-<abimajor>.dll, and to set up layer registry
-        # entries to use layers from the corresponding SDK
-        nsExec::ExecToStack 'powershell -NoLogo -NonInteractive -WindowStyle Hidden -inputformat none -ExecutionPolicy RemoteSigned -File ConfigLayersAndVulkanDLL.ps1 ${VERSION_ABI_MAJOR} 64'
-        pop $PsErr
-        ${If} $PsErr != 0
-            SetErrors
-        ${EndIf}
-        StrCpy $1 45
-        Call CheckForError
-
     # Else, running on a 32-bit OS machine
     ${Else}
 
@@ -443,26 +509,42 @@
         StrCpy $1 55
         Call CheckForError
 
-        # Run the ConfigLayersAndVulkanDLL.ps1 script to copy the most recent version of
-        # vulkan-<abimajor>-*.dll to vulkan-<abimajor>.dll, and to set up layer registry
-        # entries to use layers from the corresponding SDK
-        nsExec::ExecToStack 'powershell -NoLogo -NonInteractive -WindowStyle Hidden -inputformat none -ExecutionPolicy RemoteSigned -File ConfigLayersAndVulkanDLL.ps1 ${VERSION_ABI_MAJOR} 32'
-        pop $PsErr
-        ${If} $PsErr != 0
-            SetErrors
-        ${EndIf}
-        StrCpy $1 60
-        Call CheckForError
-
     ${Endif}
 
+    # Run the ConfigLayersAndVulkanDLL.ps1 script to copy the most recent version of
+    # vulkan-<abimajor>-*.dll to vulkan-<abimajor>.dll, and to set up layer registry
+    # entries to use layers from the corresponding SDK
+    SetOutPath "$INSTDIR"
+    Call ConfigLayersAndVulkanDLL
+    ${If} $0 != 0
+        SetOutPath "$INSTDIR"
+        Call DiagConfigLayersAndVulkanDLL
+
+        # The Powershell script failed, and we don't know why.
+        # Simply configure system to use our loader and vulkaninfo.
+        MessageBox MB_OK "Warning!$\n$\nPowershell script called by VulkanRT Installer failed with error $0. Is Powershell installed on your system?$\n$\nWill configure system with Vulkan $FileVersion." /SD IDOK
+        ${If} ${RunningX64}
+            Delete  $WINDIR\SysWow64\vulkan-${VERSION_ABI_MAJOR}.dll
+            Delete  $WINDIR\SysWow64\vulkaninfo.exe
+            CopyFiles /SILENT $WINDIR\SysWow64\vulkan-$FileVersion.dll $WINDIR\SysWow64\vulkan-${VERSION_ABI_MAJOR}.dll
+            CopyFiles /SILENT $WINDIR\SysWow64\vulkaninfo-$FileVersion.exe $WINDIR\SysWow64\vulkaninfo.exe
+        ${Endif}
+        Delete  $WINDIR\System32\vulkan-${VERSION_ABI_MAJOR}.dll
+        Delete  $WINDIR\System32\vulkaninfo.exe
+        CopyFiles /SILENT $WINDIR\System32\vulkan-$FileVersion.dll $WINDIR\System32\vulkan-${VERSION_ABI_MAJOR}.dll
+        CopyFiles /SILENT $WINDIR\System32\vulkaninfo-$FileVersion.exe $WINDIR\System32\vulkaninfo.exe
+        ClearErrors
+    ${Endif}
+    StrCpy $1 60
+    Call CheckForError
+
     # We are done using ConfigLayersAndVulkanDLL.ps1, delete it. It will be re-installed
     # by the uninstaller when it needs to be run again during uninstall.
     Delete ConfigLayersAndVulkanDLL.ps1
 
     # Finish logging and move log file to TEMP dir
     LogSet off
-    Rename "$INSTDIR\install.log" "$TEMP\VulkanRT\Install.log"
+    Rename "$INSTDIR\install.log" "$TEMP\VulkanRT\installer.log"
 
 SectionEnd
 
@@ -470,12 +552,9 @@
 !ifdef UNINSTALLER
 Section "uninstall"
 
-    # Remove contents of temp dir
-    SetOutPath "$TEMP\VulkanRT"
-    RmDir /R "$TEMP\VulkanRT"
-
     # Turn on logging
-    StrCpy $INSTDIR $TEMP\VulkanRT
+    SetOutPath "$TEMP\VulkanRT"
+    StrCpy $INSTDIR "$TEMP\VulkanRT"
     LogSet on
 
     # If running on a 64-bit OS machine, disable registry re-direct since we're running as a 32-bit executable.
@@ -490,7 +569,7 @@
     ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}${PRODUCTVERSION}" "InstallDir"
     StrCpy $IDir $0
 
-    StrCpy $1 70
+    StrCpy $1 65
     Call un.CheckForError
 
     SetOutPath "$IDir"
@@ -512,6 +591,8 @@
         Delete /REBOOTOK "$IDir\Instance_$IC\Uninstall${PRODUCTNAME}.exe"
         Rmdir /REBOOTOK "$IDir\Instance_$IC"
     ${Endif}
+    StrCpy $1 70
+    Call un.CheckForError
 
     # Modify registry for Programs and Features
 
@@ -528,6 +609,8 @@
         IntOp $IC $IC - 1
         DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}${PRODUCTVERSION}"
     ${EndIf}
+    StrCpy $1 75
+    Call un.CheckForError
 
 
     # Install the ConfigLayersAndVulkanDLL.ps1 so we can run it.
@@ -539,42 +622,66 @@
 
         # Delete vulkaninfo.exe in C:\Windows\System32 and C:\Windows\SysWOW64
         Delete /REBOOTOK $WINDIR\SysWow64\vulkaninfo.exe
-        Delete /REBOOTOK "$WINDIR\SysWow64\vulkaninfo-$FileVersion.exe"
         Delete /REBOOTOK $WINDIR\System32\vulkaninfo.exe
-        Delete /REBOOTOK "$WINDIR\System32\vulkaninfo-$FileVersion.exe"
 
-        # Delete vullkan dll files: vulkan-<majorabi>.dll and vulkan-<majorabi>-<major>-<minor>-<patch>-<buildno>.dll
+        # Delete vulkan-<majorabi>.dll in C:\Windows\System32 and C:\Windows\SysWOW64
         Delete /REBOOTOK $WINDIR\SysWow64\vulkan-${VERSION_ABI_MAJOR}.dll
-        Delete /REBOOTOK $WINDIR\SysWow64\vulkan-$FileVersion.dll
         Delete /REBOOTOK $WINDIR\System32\vulkan-${VERSION_ABI_MAJOR}.dll
-        Delete /REBOOTOK $WINDIR\System32\vulkan-$FileVersion.dll
-
-        # Run the ConfigLayersAndVulkanDLL.ps1 script to:
-        #   Copy the most recent version of vulkan-<abimajor>-*.dll to vulkan-<abimajor>.dll
-        #   Copy the most recent version of vulkaninfo-<abimajor>-*.exe to vulkaninfo.exe
-        #   Set up layer registry entries to use layers from the corresponding SDK
-        nsExec::ExecToStack 'powershell -NoLogo -NonInteractive -WindowStyle Hidden -inputformat none -ExecutionPolicy RemoteSigned -File "$IDir\ConfigLayersAndVulkanDLL.ps1" ${VERSION_ABI_MAJOR} 64'
 
     # Else, running on a 32-bit OS machine
     ${Else}
 
         # Delete vulkaninfo.exe in C:\Windows\System32
         Delete /REBOOTOK $WINDIR\System32\vulkaninfo.exe
-        Delete /REBOOTOK "$WINDIR\System32\vulkaninfo-$FileVersion.exe"
 
-        # Delete vullkan dll files: vulkan-<majorabi>.dll and vulkan-<majorabi>-<major>-<minor>-<patch>-<buildno>.dll
+        # Delete vulkan-<majorabi>.dll in C:\Windows\System32
         Delete /REBOOTOK $WINDIR\System32\vulkan-${VERSION_ABI_MAJOR}.dll
-        Delete /REBOOTOK $WINDIR\System32\vulkan-$FileVersion.dll
-
-        # Run the ConfigLayersAndVulkanDLL.ps1 script to:
-        #   Copy the most recent version of vulkan-<abimajor>-*.dll to vulkan-<abimajor>.dll
-        #   Copy the most recent version of vulkaninfo-<abimajor>-*.exe to vulkaninfo.exe
-        #   Set up layer registry entries to use layers from the corresponding SDK
-        nsExec::ExecToStack 'powershell -NoLogo -NonInteractive -WindowStyle Hidden -inputformat none -ExecutionPolicy RemoteSigned -File "$IDir\ConfigLayersAndVulkanDLL.ps1" ${VERSION_ABI_MAJOR} 32'
 
     ${EndIf}
+    StrCpy $1 80
+    Call un.CheckForError
 
-    # If Ref Count is zero, uninstall everything
+    # If Ref Count is zero, remove files in C:\Windows\System32 and C:\Windows\SysWow64
+    ${If} $IC <= 0
+
+        ${If} ${RunningX64}
+            # Delete vulkaninfo.exe in C:\Windows\System32 and C:\Windows\SysWOW64
+            Delete /REBOOTOK "$WINDIR\SysWow64\vulkaninfo-$FileVersion.exe"
+            Delete /REBOOTOK "$WINDIR\System32\vulkaninfo-$FileVersion.exe"
+            # Delete vulkan-<majorabi>-<major>-<minor>-<patch>-<buildno>.dll from sys dirs
+            Delete /REBOOTOK $WINDIR\SysWow64\vulkan-$FileVersion.dll
+            Delete /REBOOTOK $WINDIR\System32\vulkan-$FileVersion.dll
+        ${Else}
+            # Delete vulkaninfo.exe in C:\Windows\System32
+            Delete /REBOOTOK "$WINDIR\System32\vulkaninfo-$FileVersion.exe"
+            # Delete vulkan-<majorabi>-<major>-<minor>-<patch>-<buildno>.dll from sys dir
+            Delete /REBOOTOK $WINDIR\System32\vulkan-$FileVersion.dll
+        ${EndIf}
+
+    ${Endif}
+
+    # Run the ConfigLayersAndVulkanDLL.ps1 script to copy the most recent version of
+    # vulkan-<abimajor>-*.dll to vulkan-<abimajor>.dll, and to set up layer registry
+    # entries to use layers from the corresponding SDK
+    SetOutPath "$IDir"
+    Call un.ConfigLayersAndVulkanDLL
+    ${If} $0 != 0
+        SetOutPath "$IDir"
+        Call un.DiagConfigLayersAndVulkanDLL
+        MessageBox MB_OK "Warning!$\n$\nPowershell script called by VulkanRT Uninstaller failed with error $0. Is Powershell installed on your system?$\n$\nVulkan $FileVersion has been uninstalled from your system." /SD IDOK
+        ${If} ${RunningX64}
+            Delete  $WINDIR\SysWow64\vulkan-${VERSION_ABI_MAJOR}.dll
+            Delete  $WINDIR\SysWow64\vulkaninfo.exe
+        ${Endif}
+        Delete  $WINDIR\System32\vulkan-${VERSION_ABI_MAJOR}.dll
+        Delete  $WINDIR\System32\vulkaninfo.exe
+        ClearErrors
+    ${Else}
+        StrCpy $1 85
+    ${Endif}
+    Call un.CheckForError
+
+    # If Ref Count is zero, remove install dir
     ${If} $IC <= 0
 
         # Remove files in install dir
@@ -590,7 +697,7 @@
             Delete /REBOOTOK "$IDir\vulkaninfo32.exe"
         ${EndIf}
 
-        StrCpy $1 75
+        StrCpy $1 90
         Call un.CheckForError
 
         # Need to do a SetOutPath to something outside of install dir,
@@ -618,12 +725,12 @@
 
     ${Endif}
 
-    StrCpy $1 80
+    StrCpy $1 95
     Call un.CheckForError
 
-    # Finish logging and move log file to TEMP dir
+    # Finish logging
     LogSet off
-    Rename "$INSTDIR\install.log" "$INSTDIR\Uninstall.log"
+    Rename "$INSTDIR\install.log" "$TEMP\VulkanRT\uninstaller.log"
 
 SectionEnd
 !endif
@@ -667,19 +774,18 @@
 
         # Finish logging and move log file to TEMP dir
         LogSet off
-        Rename "$INSTDIR\install.log" "$TEMP\VulkanRT\install.log"
+        Rename "$INSTDIR\install.log" "$TEMP\VulkanRT\installer.log"
 
         # Copy the uninstaller to a temp folder of our own creation so we can completely
         # delete the old contents.
         SetOutPath "$TEMP\VulkanRT"
         CopyFiles "$INSTDIR\Uninstall${PRODUCTNAME}.exe" "$TEMP\VulkanRT"
 
-        # No uninstall using the version in the temporary folder.
+        # Do uninstall using the version in the temporary folder.
         ExecWait '"$TEMP\VulkanRT\Uninstall${PRODUCTNAME}.exe" /S _?=$INSTDIR'
 
         # Delete the copy of the uninstaller we ran
         Delete /REBOOTOK "$TEMP\VulkanRT\Uninstall${PRODUCTNAME}.exe"
-        RmDir /R /REBOOTOK "$TEMP\VulkanRT"
 
         # Set an error message to output
         SetErrorLevel $1
@@ -689,7 +795,7 @@
 FunctionEnd
 
 # Check for errors during uninstall.  If we hit an error, don't attempt
-# to do anything. Just set a non-zero return code and quit.
+# to do anything. Just set a non-zero return code and continue.
 Function un.CheckForError
     ${If} ${Errors}
         # IHV's using this install may want no message box.
@@ -698,11 +804,5 @@
         # Set an error message to output
         SetErrorLevel $1
 
-        # Finish logging and move log file to TEMP dir
-        LogSet off
-        Delete "$TEMP\VulkanRT\Uninstall.log"
-        Rename "$INSTDIR\install.log" "$TEMP\VulkanRT\Uninstall.log"
-
-        Quit
     ${EndIf}
 FunctionEnd